//===--- Level Zero Target RTL Implementation -----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Level Zero Event and Event Pool implementations.
//
//===----------------------------------------------------------------------===//

#include "L0Event.h"
#include "L0Trace.h"

namespace llvm::omp::target::plugin {

Expected<ze_event_handle_t> EventPoolTy::getEventLocked() {
  if (Events.empty()) {
    // Need to create a new L0 pool.
    ze_event_pool_desc_t Desc{/* stype */ ZE_STRUCTURE_TYPE_EVENT_POOL_DESC,
                              /* pNext */ nullptr,
                              /* flags */ 0,
                              /* count */ 0};
    Desc.flags = ZE_EVENT_POOL_FLAG_HOST_VISIBLE | Flags;
    Desc.count = static_cast<uint32_t>(PoolSize);

    ze_event_pool_counter_based_exp_desc_t CounterBasedDesc = {
        ZE_STRUCTURE_TYPE_COUNTER_BASED_EVENT_POOL_EXP_DESC,
        /* pNext */ nullptr,
        /* flags */ 0};
    CounterBasedDesc.flags = ZE_EVENT_POOL_COUNTER_BASED_EXP_FLAG_IMMEDIATE;

    if (UseCounterBasedEvents)
      Desc.pNext = &CounterBasedDesc;

    ze_event_pool_handle_t Pool;
    CALL_ZE_RET_ERROR(zeEventPoolCreate, Context, &Desc, 0, nullptr, &Pool);
    Pools.push_back(Pool);

    // Create events.
    ze_event_desc_t EventDesc{ZE_STRUCTURE_TYPE_EVENT_DESC, nullptr, 0, 0, 0};
    EventDesc.wait = 0;
    EventDesc.signal = ZE_EVENT_SCOPE_FLAG_HOST;
    uint32_t CreatedEvents = 0;
    for (uint32_t EventIdx = 0; EventIdx < PoolSize; EventIdx++) {
      EventDesc.index = EventIdx;
      ze_event_handle_t Event;
      ze_result_t RC;
      CALL_ZE(RC, zeEventCreate, Pool, &EventDesc, &Event);
      if (RC != ZE_RESULT_SUCCESS) {
        // Log the error and skip this event.
        ODBG(OLDT_Init) << "Warning: zeEventCreate failed at index " << EventIdx
                        << " with code " << RC << ". Skipping this event.";
        continue;
      }
      Events.push_back(Event);
      CreatedEvents++;
    }
    PoolSize = CreatedEvents;
    ODBG(OLDT_Init) << "Created a new event pool " << Pool << " with "
                    << PoolSize << " events";
  }

  auto Ret = Events.back();
  Events.pop_back();

  return Ret;
}

/// Return an event to the pool.
Error EventPoolTy::releaseEvent(ze_event_handle_t Event) {
  std::lock_guard<std::mutex> Lock(*Mtx);
  if (!UseCounterBasedEvents)
    CALL_ZE_RET_ERROR(zeEventHostReset, Event);
  Events.push_back(Event);
  return Plugin::success();
}

Expected<L0EventTy *> EventPoolTy::getEventObject() {
  std::lock_guard<std::mutex> Lock(*Mtx);

  if (EventObjects.empty()) {
    auto EventOrErr = getEventLocked();
    if (!EventOrErr)
      return EventOrErr.takeError();
    auto Event = *EventOrErr;
    auto *EventObj = new L0EventTy(Event, UseCounterBasedEvents);
    return EventObj;
  }

  auto *Ret = EventObjects.back();
  if (auto Err = Ret->reset())
    return std::move(Err);

  EventObjects.pop_back();
  return Ret;
}

Error EventPoolTy::releaseEventObject(L0EventTy *EventObj) {
  std::lock_guard<std::mutex> Lock(*Mtx);
  EventObjects.push_back(EventObj);
  return Plugin::success();
}

} // namespace llvm::omp::target::plugin
