Adding iree_hal_resource_retain/release. (#7994)
This enables type-generic resource pooling.
diff --git a/iree/hal/allocator.h b/iree/hal/allocator.h
index 9d68e31..dd7760b 100644
--- a/iree/hal/allocator.h
+++ b/iree/hal/allocator.h
@@ -187,9 +187,6 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_allocator_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_allocator_t* allocator);
iree_allocator_t(IREE_API_PTR* host_allocator)(
@@ -219,6 +216,7 @@
void(IREE_API_PTR* deallocate_buffer)(iree_hal_allocator_t* allocator,
iree_hal_buffer_t* buffer);
} iree_hal_allocator_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_allocator_vtable_t);
IREE_API_EXPORT void iree_hal_allocator_destroy(
iree_hal_allocator_t* allocator);
diff --git a/iree/hal/buffer.h b/iree/hal/buffer.h
index 326efa9..cc355d1 100644
--- a/iree/hal/buffer.h
+++ b/iree/hal/buffer.h
@@ -486,9 +486,6 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_buffer_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_buffer_t* buffer);
iree_status_t(IREE_API_PTR* map_range)(iree_hal_buffer_t* buffer,
@@ -511,6 +508,7 @@
iree_hal_buffer_t* buffer, iree_device_size_t local_byte_offset,
iree_device_size_t local_byte_length);
} iree_hal_buffer_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_buffer_vtable_t);
struct iree_hal_buffer_t {
iree_hal_resource_t resource;
diff --git a/iree/hal/command_buffer.h b/iree/hal/command_buffer.h
index e9d2c69..41087a3 100644
--- a/iree/hal/command_buffer.h
+++ b/iree/hal/command_buffer.h
@@ -517,9 +517,6 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_command_buffer_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_command_buffer_t* command_buffer);
void*(IREE_API_PTR* dyn_cast)(iree_hal_command_buffer_t* command_buffer,
@@ -612,6 +609,7 @@
iree_hal_buffer_t* workgroups_buffer,
iree_device_size_t workgroups_offset);
} iree_hal_command_buffer_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_command_buffer_vtable_t);
struct iree_hal_command_buffer_t {
iree_hal_resource_t resource;
diff --git a/iree/hal/descriptor_set.h b/iree/hal/descriptor_set.h
index 6753492..11c7957 100644
--- a/iree/hal/descriptor_set.h
+++ b/iree/hal/descriptor_set.h
@@ -88,11 +88,9 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_descriptor_set_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_descriptor_set_t* descriptor_set);
} iree_hal_descriptor_set_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_descriptor_set_vtable_t);
IREE_API_EXPORT void iree_hal_descriptor_set_destroy(
iree_hal_descriptor_set_t* descriptor_set);
diff --git a/iree/hal/descriptor_set_layout.h b/iree/hal/descriptor_set_layout.h
index 68c1248..36e3940 100644
--- a/iree/hal/descriptor_set_layout.h
+++ b/iree/hal/descriptor_set_layout.h
@@ -89,12 +89,10 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_descriptor_set_layout_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(
iree_hal_descriptor_set_layout_t* descriptor_set_layout);
} iree_hal_descriptor_set_layout_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_descriptor_set_layout_vtable_t);
IREE_API_EXPORT void iree_hal_descriptor_set_layout_destroy(
iree_hal_descriptor_set_layout_t* descriptor_set_layout);
diff --git a/iree/hal/device.h b/iree/hal/device.h
index 1d77d27..275b9f1 100644
--- a/iree/hal/device.h
+++ b/iree/hal/device.h
@@ -244,9 +244,6 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_device_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_device_t* device);
iree_string_view_t(IREE_API_PTR* id)(iree_hal_device_t* device);
@@ -315,6 +312,7 @@
iree_status_t(IREE_API_PTR* wait_idle)(iree_hal_device_t* device,
iree_timeout_t timeout);
} iree_hal_device_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_device_vtable_t);
IREE_API_EXPORT void iree_hal_device_destroy(iree_hal_device_t* device);
diff --git a/iree/hal/driver.h b/iree/hal/driver.h
index 8cd6076..65cbd66 100644
--- a/iree/hal/driver.h
+++ b/iree/hal/driver.h
@@ -94,9 +94,6 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_driver_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_driver_t* driver);
iree_status_t(IREE_API_PTR* query_available_devices)(
@@ -109,6 +106,7 @@
iree_allocator_t allocator,
iree_hal_device_t** out_device);
} iree_hal_driver_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_driver_vtable_t);
IREE_API_EXPORT void iree_hal_driver_destroy(iree_hal_driver_t* driver);
diff --git a/iree/hal/event.h b/iree/hal/event.h
index 911e50f..a6ea312 100644
--- a/iree/hal/event.h
+++ b/iree/hal/event.h
@@ -51,11 +51,9 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_event_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_event_t* event);
} iree_hal_event_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_event_vtable_t);
IREE_API_EXPORT void iree_hal_event_destroy(iree_hal_event_t* event);
diff --git a/iree/hal/executable.h b/iree/hal/executable.h
index 7cabcf4..561ed3a 100644
--- a/iree/hal/executable.h
+++ b/iree/hal/executable.h
@@ -51,11 +51,9 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_executable_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_executable_t* executable);
} iree_hal_executable_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_executable_vtable_t);
IREE_API_EXPORT void iree_hal_executable_destroy(
iree_hal_executable_t* executable);
diff --git a/iree/hal/executable_cache.h b/iree/hal/executable_cache.h
index d75cfcb..50945f8 100644
--- a/iree/hal/executable_cache.h
+++ b/iree/hal/executable_cache.h
@@ -171,9 +171,6 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_executable_cache_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_executable_cache_t* executable_cache);
bool(IREE_API_PTR* can_prepare_format)(
@@ -186,6 +183,7 @@
const iree_hal_executable_spec_t* executable_spec,
iree_hal_executable_t** out_executable);
} iree_hal_executable_cache_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_executable_cache_vtable_t);
IREE_API_EXPORT void iree_hal_executable_cache_destroy(
iree_hal_executable_cache_t* executable_cache);
diff --git a/iree/hal/executable_layout.h b/iree/hal/executable_layout.h
index 1fbcd48..7fa1a21 100644
--- a/iree/hal/executable_layout.h
+++ b/iree/hal/executable_layout.h
@@ -64,11 +64,9 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_executable_layout_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_executable_layout_t* executable_layout);
} iree_hal_executable_layout_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_executable_layout_vtable_t);
IREE_API_EXPORT void iree_hal_executable_layout_destroy(
iree_hal_executable_layout_t* executable_layout);
diff --git a/iree/hal/resource.h b/iree/hal/resource.h
index 3f4c794..0f7abbe 100644
--- a/iree/hal/resource.h
+++ b/iree/hal/resource.h
@@ -7,6 +7,7 @@
#ifndef IREE_HAL_RESOURCE_H_
#define IREE_HAL_RESOURCE_H_
+#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@@ -33,6 +34,7 @@
iree_atomic_ref_count_t ref_count;
// Opaque vtable for the resource object.
+ // Must start with iree_hal_resource_vtable_t at offset 0.
//
// NOTE: this field may be hidden in the future. Only use this for
// IREE_HAL_VTABLE_DISPATCH and not equality/direct dereferencing.
@@ -41,12 +43,54 @@
// TODO(benvanik): debug string/logging utilities.
} iree_hal_resource_t;
+// Base vtable for all resources.
+// This provides the base functions required to generically manipulate resources
+// of various types.
+//
+// This must be aliased at offset 0 of all typed vtables:
+// typedef struct iree_hal_foo_vtable_t {
+// void(IREE_API_PTR* destroy)(...);
+// void(IREE_API_PTR* foo_method)(...);
+// } iree_hal_foo_vtable_t;
+typedef struct iree_hal_resource_vtable_t {
+ // Destroys the resource upon the final reference being released.
+ // The resource pointer must be assumed invalid upon return from the function
+ // (even if in some implementations its returned to a pool and still live).
+ void(IREE_API_PTR* destroy)(iree_hal_resource_t* resource);
+} iree_hal_resource_vtable_t;
+
+// Verifies that the vtable has the right resource sub-vtable.
+#define IREE_HAL_ASSERT_VTABLE_LAYOUT(vtable_type) \
+ static_assert(offsetof(vtable_type, destroy) == 0, \
+ "iree_hal_resource_vtable_t must be at offset 0");
+
+// Initializes the base resource type.
static inline void iree_hal_resource_initialize(
const void* vtable, iree_hal_resource_t* out_resource) {
iree_atomic_ref_count_init(&out_resource->ref_count);
out_resource->vtable = vtable;
}
+// Retains a resource for the caller.
+static inline void iree_hal_resource_retain(const void* any_resource) {
+ iree_hal_resource_t* resource = (iree_hal_resource_t*)any_resource;
+ if (IREE_LIKELY(resource)) {
+ iree_atomic_ref_count_inc(&resource->ref_count);
+ }
+}
+
+// Releases a resource and destroys it if there are no more references.
+// This routes through the vtable and can disable optimizations; always prefer
+// to use the type-specific release functions (such as iree_hal_buffer_release)
+// to allow for more optimizations and better compile-time type safety.
+static inline void iree_hal_resource_release(const void* any_resource) {
+ iree_hal_resource_t* resource = (iree_hal_resource_t*)any_resource;
+ if (IREE_LIKELY(resource) &&
+ iree_atomic_ref_count_dec(&resource->ref_count) == 1) {
+ ((iree_hal_resource_vtable_t*)resource->vtable)->destroy(resource);
+ }
+}
+
// Returns true if the |resource| has the given |vtable| type.
// This is *not* a way to ensure that an instance is of a specific type but
// instead that it has a compatible vtable. This is because LTO may very rarely
diff --git a/iree/hal/semaphore.h b/iree/hal/semaphore.h
index 5eded01..afc8959 100644
--- a/iree/hal/semaphore.h
+++ b/iree/hal/semaphore.h
@@ -114,9 +114,6 @@
//===----------------------------------------------------------------------===//
typedef struct iree_hal_semaphore_vtable_t {
- // << HAL C porting in progress >>
- IREE_API_UNSTABLE
-
void(IREE_API_PTR* destroy)(iree_hal_semaphore_t* semaphore);
iree_status_t(IREE_API_PTR* query)(iree_hal_semaphore_t* semaphore,
@@ -129,6 +126,7 @@
iree_status_t(IREE_API_PTR* wait)(iree_hal_semaphore_t* semaphore,
uint64_t value, iree_timeout_t timeout);
} iree_hal_semaphore_vtable_t;
+IREE_HAL_ASSERT_VTABLE_LAYOUT(iree_hal_semaphore_vtable_t);
IREE_API_EXPORT void iree_hal_semaphore_destroy(
iree_hal_semaphore_t* semaphore);