[metal] Improve order in device creation Change it to follow device struct allocation, initialization, and subresource creation. This way we can handle destruction on failures better.
diff --git a/experimental/metal/metal_device.m b/experimental/metal/metal_device.m index 191bd25..5e697cd 100644 --- a/experimental/metal/metal_device.m +++ b/experimental/metal/metal_device.m
@@ -94,7 +94,23 @@ iree_host_size_t total_size = iree_sizeof_struct(*device) + identifier.size; IREE_RETURN_IF_ERROR(iree_allocator_malloc(host_allocator, total_size, (void**)&device)); + iree_hal_resource_initialize(&iree_hal_metal_device_vtable, &device->resource); + iree_string_view_append_to_buffer(identifier, &device->identifier, + (char*)device + iree_sizeof_struct(*device)); + iree_arena_block_pool_initialize(params->arena_block_size, host_allocator, &device->block_pool); + device->params = *params; + device->host_allocator = host_allocator; + + device->device = [metal_device retain]; // +1 id<MTLCommandQueue> metal_queue = [metal_device newCommandQueue]; // +1 + device->queue = metal_queue; + device->command_buffer_resource_reference_mode = params->command_buffer_resource_reference_mode; + dispatch_queue_attr_t queue_attr = dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, /*relative_priority=*/0); + device->semaphore_notification_queue = dispatch_queue_create("dev.iree.queue.metal", queue_attr); + device->event_listener = [[MTLSharedEventListener alloc] + initWithDispatchQueue:device->semaphore_notification_queue]; // +1 + device->capture_manager = NULL; iree_status_t status = iree_hal_metal_allocator_create(metal_device, #if defined(IREE_PLATFORM_MACOS) @@ -103,40 +119,20 @@ params->resource_hazard_tracking_mode, host_allocator, &device->device_allocator); - iree_hal_metal_builtin_executable_t* builtin_executable = NULL; if (iree_status_is_ok(status)) { - status = - iree_hal_metal_builtin_executable_create(metal_device, host_allocator, &builtin_executable); - } else { - iree_hal_device_release((iree_hal_device_t*)device); + status = iree_hal_metal_builtin_executable_create(metal_device, host_allocator, + &device->builtin_executable); } if (iree_status_is_ok(status)) { status = iree_hal_metal_staging_buffer_initialize( metal_device, params->queue_uniform_buffer_size, &device->staging_buffer); - } else { - iree_hal_device_release((iree_hal_device_t*)device); } if (iree_status_is_ok(status)) { - iree_hal_resource_initialize(&iree_hal_metal_device_vtable, &device->resource); - iree_string_view_append_to_buffer(identifier, &device->identifier, - (char*)device + iree_sizeof_struct(*device)); - iree_arena_block_pool_initialize(params->arena_block_size, host_allocator, &device->block_pool); - device->params = *params; - device->host_allocator = host_allocator; - device->device = [metal_device retain]; // +1 - device->queue = metal_queue; - device->command_buffer_resource_reference_mode = params->command_buffer_resource_reference_mode; - device->builtin_executable = builtin_executable; - dispatch_queue_attr_t queue_attr = dispatch_queue_attr_make_with_qos_class( - DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, /*relative_priority=*/0); - device->semaphore_notification_queue = - dispatch_queue_create("dev.iree.queue.metal", queue_attr); - device->event_listener = [[MTLSharedEventListener alloc] - initWithDispatchQueue:device->semaphore_notification_queue]; // +1 - device->capture_manager = NULL; *out_device = (iree_hal_device_t*)device; + } else { + iree_hal_device_release((iree_hal_device_t*)device); } return status; }