// 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_atomic_int64_t value;
} 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) {
  iree_hal_rocm_semaphore_t* semaphore =
      iree_hal_rocm_semaphore_cast(base_semaphore);
  // TODO: Support semaphores completely.
  *out_value =
      iree_atomic_load_int64(&semaphore->value, iree_memory_order_acquire);
  return iree_ok_status();
}

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,
};
