// Copyright 2021 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

#include "experimental/rocm/event_semaphore.h"

#include <stddef.h>

#include "iree/base/api.h"
#include "iree/base/tracing.h"
#include "iree/hal/utils/semaphore_base.h"

typedef struct iree_hal_rocm_semaphore_t {
  iree_hal_semaphore_t base;
  iree_hal_rocm_context_wrapper_t* context;
} iree_hal_rocm_semaphore_t;

static const iree_hal_semaphore_vtable_t iree_hal_rocm_semaphore_vtable;

static iree_hal_rocm_semaphore_t* iree_hal_rocm_semaphore_cast(
    iree_hal_semaphore_t* base_value) {
  IREE_HAL_ASSERT_TYPE(base_value, &iree_hal_rocm_semaphore_vtable);
  return (iree_hal_rocm_semaphore_t*)base_value;
}

iree_status_t iree_hal_rocm_semaphore_create(
    iree_hal_rocm_context_wrapper_t* context, uint64_t initial_value,
    iree_hal_semaphore_t** out_semaphore) {
  IREE_ASSERT_ARGUMENT(context);
  IREE_ASSERT_ARGUMENT(out_semaphore);
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_hal_rocm_semaphore_t* semaphore = NULL;
  iree_status_t status = iree_allocator_malloc(
      context->host_allocator, sizeof(*semaphore), (void**)&semaphore);
  if (iree_status_is_ok(status)) {
    iree_hal_semaphore_initialize(&iree_hal_rocm_semaphore_vtable,
                                  &semaphore->base);
    semaphore->context = context;
    *out_semaphore = &semaphore->base;
  }

  IREE_TRACE_ZONE_END(z0);
  return status;
}

static void iree_hal_rocm_semaphore_destroy(
    iree_hal_semaphore_t* base_semaphore) {
  iree_hal_rocm_semaphore_t* semaphore =
      iree_hal_rocm_semaphore_cast(base_semaphore);
  iree_allocator_t host_allocator = semaphore->context->host_allocator;
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_hal_semaphore_deinitialize(&semaphore->base);
  iree_allocator_free(host_allocator, semaphore);

  IREE_TRACE_ZONE_END(z0);
}

static iree_status_t iree_hal_rocm_semaphore_query(
    iree_hal_semaphore_t* base_semaphore, uint64_t* out_value) {
  // TODO: Support semaphores completely.
  *out_value = 0;
  return iree_make_status(IREE_STATUS_UNIMPLEMENTED, "Not impemented on rocm");
}

static iree_status_t iree_hal_rocm_semaphore_signal(
    iree_hal_semaphore_t* base_semaphore, uint64_t new_value) {
  iree_hal_rocm_semaphore_t* semaphore =
      iree_hal_rocm_semaphore_cast(base_semaphore);
  // TODO: Support semaphores completely. Return OK currently as everything is
  // synchronized for each submit to allow things to run.
  iree_hal_semaphore_poll(&semaphore->base);
  return iree_ok_status();
}

static void iree_hal_rocm_semaphore_fail(iree_hal_semaphore_t* base_semaphore,
                                         iree_status_t status) {
  iree_hal_rocm_semaphore_t* semaphore =
      iree_hal_rocm_semaphore_cast(base_semaphore);
  // TODO: save status and mark timepoint as failed.
  iree_status_ignore(status);
  iree_hal_semaphore_poll(&semaphore->base);
}

static iree_status_t iree_hal_rocm_semaphore_wait(
    iree_hal_semaphore_t* base_semaphore, uint64_t value,
    iree_timeout_t timeout) {
  iree_hal_rocm_semaphore_t* semaphore =
      iree_hal_rocm_semaphore_cast(base_semaphore);
  // TODO: Support semaphores completely. Return OK currently as everything is
  // synchronized for each submit to allow things to run.
  iree_hal_semaphore_poll(&semaphore->base);
  return iree_ok_status();
}

static const iree_hal_semaphore_vtable_t iree_hal_rocm_semaphore_vtable = {
    .destroy = iree_hal_rocm_semaphore_destroy,
    .query = iree_hal_rocm_semaphore_query,
    .signal = iree_hal_rocm_semaphore_signal,
    .fail = iree_hal_rocm_semaphore_fail,
    .wait = iree_hal_rocm_semaphore_wait,
};
