/*
 * Copyright © 2019 Google LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "tu_private.h"

#include <fcntl.h>
#include <libsync.h>
#include <unistd.h>

#include "util/os_file.h"
#include "util/os_time.h"

/**
 * Internally, a fence can be in one of these states.
 */
enum tu_fence_state
{
   TU_FENCE_STATE_RESET,
   TU_FENCE_STATE_PENDING,
   TU_FENCE_STATE_SIGNALED,
};

static enum tu_fence_state
tu_fence_get_state(const struct tu_fence *fence)
{
   if (fence->signaled)
      assert(fence->fd < 0);

   if (fence->signaled)
      return TU_FENCE_STATE_SIGNALED;
   else if (fence->fd >= 0)
      return TU_FENCE_STATE_PENDING;
   else
      return TU_FENCE_STATE_RESET;
}

static void
tu_fence_set_state(struct tu_fence *fence, enum tu_fence_state state, int fd)
{
   if (fence->fd >= 0)
      close(fence->fd);

   switch (state) {
   case TU_FENCE_STATE_RESET:
      assert(fd < 0);
      fence->signaled = false;
      fence->fd = -1;
      break;
   case TU_FENCE_STATE_PENDING:
      assert(fd >= 0);
      fence->signaled = false;
      fence->fd = fd;
      break;
   case TU_FENCE_STATE_SIGNALED:
      assert(fd < 0);
      fence->signaled = true;
      fence->fd = -1;
      break;
   default:
      unreachable("unknown fence state");
      break;
   }
}

void
tu_fence_init(struct tu_fence *fence, bool signaled)
{
   fence->signaled = signaled;
   fence->fd = -1;
   fence->fence_wsi = NULL;
}

void
tu_fence_finish(struct tu_fence *fence)
{
   if (fence->fd >= 0)
      close(fence->fd);
   if (fence->fence_wsi)
      fence->fence_wsi->destroy(fence->fence_wsi);
}

/**
 * Update the associated fd of a fence.  Ownership of \a fd is transferred to
 * \a fence.
 *
 * This function does not block.  \a fence can also be in any state when this
 * function is called.  To be able to do that, the caller must make sure that,
 * when both the currently associated fd and the new fd are valid, they are on
 * the same timeline with the new fd being later on the timeline.
 */
void
tu_fence_update_fd(struct tu_fence *fence, int fd)
{
   const enum tu_fence_state state =
      fd >= 0 ? TU_FENCE_STATE_PENDING : TU_FENCE_STATE_SIGNALED;
   tu_fence_set_state(fence, state, fd);
}

/**
 * Make a fence a copy of another fence.  \a fence must be in the reset state.
 */
void
tu_fence_copy(struct tu_fence *fence, const struct tu_fence *src)
{
   assert(tu_fence_get_state(fence) == TU_FENCE_STATE_RESET);

   /* dup src->fd */
   int fd = -1;
   if (src->fd >= 0) {
      fd = os_dupfd_cloexec(src->fd);
      if (fd < 0) {
         tu_loge("failed to dup fd %d for fence", src->fd);
         sync_wait(src->fd, -1);
      }
   }

   tu_fence_update_fd(fence, fd);
}

/**
 * Wait until a fence is idle (i.e., not pending).
 */
void
tu_fence_wait_idle(struct tu_fence *fence)
{
   if (fence->fd >= 0) {
      if (sync_wait(fence->fd, -1))
         tu_loge("sync_wait on fence fd %d failed", fence->fd);

      tu_fence_set_state(fence, TU_FENCE_STATE_SIGNALED, -1);
   }
}

VkResult
tu_CreateFence(VkDevice _device,
               const VkFenceCreateInfo *pCreateInfo,
               const VkAllocationCallbacks *pAllocator,
               VkFence *pFence)
{
   TU_FROM_HANDLE(tu_device, device, _device);

   struct tu_fence *fence =
         vk_object_alloc(&device->vk, pAllocator, sizeof(*fence),
                         VK_OBJECT_TYPE_FENCE);
   if (!fence)
      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);

   tu_fence_init(fence, pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT);

   *pFence = tu_fence_to_handle(fence);

   return VK_SUCCESS;
}

void
tu_DestroyFence(VkDevice _device,
                VkFence _fence,
                const VkAllocationCallbacks *pAllocator)
{
   TU_FROM_HANDLE(tu_device, device, _device);
   TU_FROM_HANDLE(tu_fence, fence, _fence);

   if (!fence)
      return;

   tu_fence_finish(fence);

   vk_object_free(&device->vk, pAllocator, fence);
}

/**
 * Initialize a pollfd array from fences.
 */
static nfds_t
tu_fence_init_poll_fds(uint32_t fence_count,
                       const VkFence *fences,
                       bool wait_all,
                       struct pollfd *fds)
{
   nfds_t nfds = 0;
   for (uint32_t i = 0; i < fence_count; i++) {
      TU_FROM_HANDLE(tu_fence, fence, fences[i]);

      /* skip wsi fences */
      if (fence->fence_wsi)
            continue;

      if (fence->signaled) {
         if (wait_all) {
            /* skip signaled fences */
            continue;
         } else {
            /* no need to poll any fd */
            nfds = 0;
            break;
         }
      }

      /* negative fds are never ready, which is the desired behavior */
      fds[nfds].fd = fence->fd;
      fds[nfds].events = POLLIN;
      fds[nfds].revents = 0;
      nfds++;
   }

   return nfds;
}

/**
 * Translate timeout from nanoseconds to milliseconds for poll().
 */
static int
tu_fence_get_poll_timeout(uint64_t timeout_ns)
{
   const uint64_t ns_per_ms = 1000 * 1000;
   uint64_t timeout_ms = timeout_ns / ns_per_ms;

   /* round up if needed */
   if (timeout_ns - timeout_ms * ns_per_ms >= ns_per_ms / 2)
      timeout_ms++;

   return timeout_ms < INT_MAX ? timeout_ms : INT_MAX;
}

/**
 * Poll a pollfd array.
 */
static VkResult
tu_fence_poll_fds(struct pollfd *fds, nfds_t nfds, uint64_t *timeout_ns)
{
   while (true) {
      /* poll */
      uint64_t duration = os_time_get_nano();
      int ret = poll(fds, nfds, tu_fence_get_poll_timeout(*timeout_ns));
      duration = os_time_get_nano() - duration;

      /* update timeout_ns */
      if (*timeout_ns > duration)
         *timeout_ns -= duration;
      else
         *timeout_ns = 0;

      if (ret > 0) {
         return VK_SUCCESS;
      } else if (ret == 0) {
         if (!*timeout_ns)
            return VK_TIMEOUT;
      } else if (errno != EINTR && errno != EAGAIN) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      }
   }
}

/**
 * Update a pollfd array and the fence states.  This should be called after a
 * successful call to tu_fence_poll_fds.
 */
static nfds_t
tu_fence_update_fences_and_poll_fds(uint32_t fence_count,
                                    const VkFence *fences,
                                    bool wait_all,
                                    struct pollfd *fds)
{
   uint32_t nfds = 0;
   uint32_t fds_idx = 0;
   for (uint32_t i = 0; i < fence_count; i++) {
      TU_FROM_HANDLE(tu_fence, fence, fences[i]);

      /* skip wsi fences */
      if (fence->fence_wsi)
            continue;

      /* no signaled fence in fds */
      if (fence->signaled)
         continue;

      /* fds[fds_idx] corresponds to fences[i] */
      assert(fence->fd == fds[fds_idx].fd);

      assert(nfds <= fds_idx && fds_idx <= i);

      /* fd is ready (errors are treated as ready) */
      if (fds[fds_idx].revents) {
         tu_fence_set_state(fence, TU_FENCE_STATE_SIGNALED, -1);
      } else if (wait_all) {
         /* add to fds again for another poll */
         fds[nfds].fd = fence->fd;
         fds[nfds].events = POLLIN;
         fds[nfds].revents = 0;
         nfds++;
      }

      fds_idx++;
   }

   return nfds;
}

VkResult
tu_WaitForFences(VkDevice _device,
                 uint32_t fenceCount,
                 const VkFence *pFences,
                 VkBool32 waitAll,
                 uint64_t timeout)
{
   TU_FROM_HANDLE(tu_device, device, _device);

   if (tu_device_is_lost(device))
      return VK_ERROR_DEVICE_LOST;

   /* add a simpler path for when fenceCount == 1? */

   struct pollfd stack_fds[8];
   struct pollfd *fds = stack_fds;
   if (fenceCount > ARRAY_SIZE(stack_fds)) {
      fds = vk_alloc(&device->vk.alloc, sizeof(*fds) * fenceCount, 8,
                     VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
      if (!fds)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
   }

   /* set up pollfd array and start polling */
   nfds_t nfds = tu_fence_init_poll_fds(fenceCount, pFences, waitAll, fds);
   VkResult result = VK_SUCCESS;
   while (nfds) {
      result = tu_fence_poll_fds(fds, nfds, &timeout);
      if (result != VK_SUCCESS)
         break;
      nfds = tu_fence_update_fences_and_poll_fds(fenceCount, pFences, waitAll,
                                                 fds);
   }

   if (fds != stack_fds)
      vk_free(&device->vk.alloc, fds);

   if (result != VK_SUCCESS)
      return result;

   for (uint32_t i = 0; i < fenceCount; ++i) {
      TU_FROM_HANDLE(tu_fence, fence, pFences[i]);
      if (fence->fence_wsi) {
         VkResult result = fence->fence_wsi->wait(fence->fence_wsi, timeout);
         if (result != VK_SUCCESS)
            return result;
      }
   }

   return result;
}

VkResult
tu_ResetFences(VkDevice _device, uint32_t fenceCount, const VkFence *pFences)
{
   for (unsigned i = 0; i < fenceCount; ++i) {
      TU_FROM_HANDLE(tu_fence, fence, pFences[i]);
      assert(tu_fence_get_state(fence) != TU_FENCE_STATE_PENDING);
      tu_fence_set_state(fence, TU_FENCE_STATE_RESET, -1);
   }

   return VK_SUCCESS;
}

VkResult
tu_GetFenceStatus(VkDevice _device, VkFence _fence)
{
   TU_FROM_HANDLE(tu_fence, fence, _fence);

   if (fence->fd >= 0) {
      int err = sync_wait(fence->fd, 0);
      if (!err)
         tu_fence_set_state(fence, TU_FENCE_STATE_SIGNALED, -1);
      else if (err && errno != ETIME)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
   }
   if (fence->fence_wsi) {
      VkResult result = fence->fence_wsi->wait(fence->fence_wsi, 0);

      if (result != VK_SUCCESS) {
         if (result == VK_TIMEOUT)
            return VK_NOT_READY;
         return result;
      }
   }

   return fence->signaled ? VK_SUCCESS : VK_NOT_READY;
}
