//===-- OpenMP/InteropAPI.h - OpenMP interoperability types and API - C++ -===//
//
// Part of the LLVM Project, 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
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//

#ifndef OMPTARGET_OPENMP_INTEROP_API_H
#define OMPTARGET_OPENMP_INTEROP_API_H

#include "omp.h"

#include "PerThreadTable.h"
#include "omptarget.h"

extern "C" {

typedef enum kmp_interop_type_t {
  kmp_interop_type_unknown = -1,
  kmp_interop_type_target,
  kmp_interop_type_targetsync,
} kmp_interop_type_t;

struct interop_attrs_t {
  bool inorder : 1;
  int reserved : 31;

  /// Check if the supported attributes are compatible with the current
  ///   attributes. Only if an attribute is supported can the value be true,
  ///   otherwise it needs to be false
  bool checkSupportedOnly(interop_attrs_t supported) const {
    return supported.inorder || (!supported.inorder && !inorder);
  }
};

struct interop_spec_t {
  int32_t fr_id;
  interop_attrs_t attrs; // Common attributes
  int64_t impl_attrs; // Implementation specific attributes (recognized by each
                      // plugin)
};

struct interop_flags_t {
  bool implicit : 1; // dispatch (true) or interop (false)
  bool nowait : 1;   // has nowait flag
  int reserved : 30;
};

struct interop_ctx_t {
  uint32_t version; // version of the interface (current is 0)
  interop_flags_t flags;
  int gtid;
};

struct dep_pack_t {
  int32_t ndeps;
  int32_t ndeps_noalias;
  kmp_depend_info_t *deplist;
  kmp_depend_info_t *noalias_deplist;
};

struct omp_interop_val_t;

typedef void ompx_interop_cb_t(omp_interop_val_t *interop, void *data);

struct omp_interop_cb_instance_t {
  ompx_interop_cb_t *cb;
  void *data;

  omp_interop_cb_instance_t(ompx_interop_cb_t *cb, void *data)
      : cb(cb), data(data) {}

  void operator()(omp_interop_val_t *interop) { cb(interop, data); }
};

/// The interop value type, aka. the interop object.
typedef struct omp_interop_val_t {
  /// Device and interop-type are determined at construction time and fix.
  omp_interop_val_t(intptr_t device_id, kmp_interop_type_t interop_type)
      : interop_type(interop_type), device_id(device_id) {}
  const char *err_str = nullptr;
  __tgt_async_info *async_info = nullptr;
  __tgt_device_info device_info;
  const kmp_interop_type_t interop_type;
  const intptr_t device_id;
  omp_vendor_id_t vendor_id = omp_vendor_llvm;
  tgt_foreign_runtime_id_t fr_id = tgt_fr_none;
  interop_attrs_t attrs{false, 0}; // Common prefer specification attributes
  int64_t impl_attrs = 0; // Implementation prefer specification attributes

  // Constants
  static constexpr int no_owner = -1; // This interop has no current owner

  void *rtl_property = nullptr; // Plugin dependent information
  // For implicitly created Interop objects (e.g., from a dispatch construct)
  // who owns the object
  int owner_gtid = no_owner;
  // Marks whether the object was requested since the last time it was synced
  bool clean = true;

  typedef llvm::SmallVector<omp_interop_cb_instance_t> callback_list_t;

  callback_list_t completion_cbs;

  void reset() {
    owner_gtid = no_owner;
    markClean();
    clearCompletionCbs();
  }

  llvm::Expected<DeviceTy &> getDevice() const;

  bool hasOwner() const { return owner_gtid != no_owner; }

  void setOwner(int gtid) { owner_gtid = gtid; }
  bool isOwnedBy(int gtid) { return owner_gtid == gtid; }
  bool isCompatibleWith(int32_t InteropType, const interop_spec_t &Spec);
  bool isCompatibleWith(int32_t InteropType, const interop_spec_t &Spec,
                        int64_t DeviceNum, int gtid);
  void markClean() { clean = true; }
  void markDirty() { clean = false; }
  bool isClean() const { return clean; }

  int32_t flush(DeviceTy &Device);
  int32_t sync_barrier(DeviceTy &Device);
  int32_t async_barrier(DeviceTy &Device);
  int32_t release(DeviceTy &Device);

  void addCompletionCb(ompx_interop_cb_t *cb, void *data) {
    completion_cbs.push_back(omp_interop_cb_instance_t(cb, data));
  }

  int numCompletionCbs() const { return completion_cbs.size(); }
  void clearCompletionCbs() { completion_cbs.clear(); }

  void runCompletionCbs() {
    for (auto &cbInstance : completion_cbs)
      cbInstance(this);
    clearCompletionCbs();
  }
} omp_interop_val_t;

} // extern "C"

struct InteropTableEntry {
  using ContainerTy = typename std::vector<omp_interop_val_t *>;
  using iterator = typename ContainerTy::iterator;

  ContainerTy Interops;

  static constexpr int reservedEntriesPerThread =
      20; // reserve some entries to avoid reallocation

  void add(omp_interop_val_t *obj) {
    if (Interops.capacity() == 0)
      Interops.reserve(reservedEntriesPerThread);
    Interops.push_back(obj);
  }

  template <class ClearFuncTy> void clear(ClearFuncTy f) {
    for (auto &Obj : Interops) {
      f(Obj);
    }
  }

  /// vector interface
  int size() const { return Interops.size(); }
  iterator begin() { return Interops.begin(); }
  iterator end() { return Interops.end(); }
  iterator erase(iterator it) { return Interops.erase(it); }
};

struct InteropTblTy
    : public PerThreadTable<InteropTableEntry, omp_interop_val_t *> {
  void clear();
};

void syncImplicitInterops(int gtid, void *event);

#endif // OMPTARGET_OPENMP_INTEROP_API_H
