// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/sync/completion.h>
#include <limits.h>
#include <stdatomic.h>
#include <zircon/syscalls.h>

enum int32_t {
  UNSIGNALED = 0,
  UNSIGNALED_WITH_WAITERS = 1,
  SIGNALED = 2,
};

zx_status_t sync_completion_wait(sync_completion_t* completion, zx_duration_t timeout) {
  zx_time_t deadline =
      (timeout == ZX_TIME_INFINITE) ? ZX_TIME_INFINITE : zx_deadline_after(timeout);
  return sync_completion_wait_deadline(completion, deadline);
}

zx_status_t sync_completion_wait_deadline(sync_completion_t* completion, zx_time_t deadline) {
  // TODO(kulakowski): With a little more state (a waiters count),
  // this could optimistically spin before entering the kernel.

  atomic_int* futex = &completion->futex;
  int32_t prev_value = UNSIGNALED;

  atomic_compare_exchange_strong(futex, &prev_value, UNSIGNALED_WITH_WAITERS);

  // If we had been signaled, then just get out.  Because of the CMPX, we are
  // still signaled.
  if (prev_value == SIGNALED) {
    return ZX_OK;
  }

  // There are only two choices here.  The previous state was
  // UNSIGNALED_WITH_WAITERS (and we changed nothing), or it was UNSIGNALED
  // (and we just transitioned it to UWW).  Either way, we expect the state to
  // be UWW by the time we join the wait queue.  If it is anything else
  // (BAD_STATE), then it must have achieved SIGNALED at some point in the
  // past.  Likewise (ignoring the race described below), if we get ZX_OK
  // back, then we must have been woken by some other thread which was
  // signaling our completion.
  switch (_zx_futex_wait(futex, UNSIGNALED_WITH_WAITERS, ZX_HANDLE_INVALID, deadline)) {
    case ZX_OK:
    case ZX_ERR_BAD_STATE:
      return ZX_OK;

    case ZX_ERR_TIMED_OUT:
      return ZX_ERR_TIMED_OUT;

    case ZX_ERR_INVALID_ARGS:
    default:
      __builtin_trap();
  }
}

void sync_completion_signal(sync_completion_t* completion) {
  atomic_int* futex = &completion->futex;
  int32_t expected = atomic_load_explicit(futex, memory_order_acquire);

  do {
    if (expected == SIGNALED) {
      return;
    }

    // ASSERT that the state was either or UNSIGNALED or
    // UNSIGNALED_WITH_WAITERS.  Anything else is an indication of either a bad
    // pointer being passed to us, or memory corruption.
    if ((expected != UNSIGNALED) && (expected != UNSIGNALED_WITH_WAITERS)) {
      __builtin_trap();
    }

    // Exchange what was with SIGNALED.  If we fail, just restart.
  } while (!atomic_compare_exchange_weak_explicit(futex, &expected, SIGNALED, memory_order_seq_cst,
                                                  memory_order_acquire));

  // Success!  If there had been waiters, wake them up now.
  if (expected == UNSIGNALED_WITH_WAITERS) {
    _zx_futex_wake(futex, UINT32_MAX);
  }
}

void sync_completion_signal_requeue(sync_completion_t* completion, zx_futex_t* requeue_target,
                                    zx_handle_t requeue_target_owner) {
  atomic_store(&completion->futex, SIGNALED);
  // Note that _zx_futex_requeue() will check the value of &completion->futex
  // and return ZX_ERR_BAD_STATE if it is not SIGNALED. The only way that could
  // happen is racing with sync_completion_reset(). This is not an intended use
  // case for this function: we only expect it to be used internally by libsync
  // and without sync_completion_reset().
  //
  // However, if this theoretical scenario actually occurs, we can still safely
  // ignore the error: there is no point in waking up the waiters since they
  // would find an UNSIGNALED value and go back to sleep.
  _zx_futex_requeue(&completion->futex, 0, SIGNALED, requeue_target, UINT32_MAX,
                    requeue_target_owner);
}

void sync_completion_reset(sync_completion_t* completion) {
  atomic_int* futex = &completion->futex;
  int expected = SIGNALED;

  if (!atomic_compare_exchange_strong(futex, &expected, UNSIGNALED)) {
    // If we were not SIGNALED, then we had better have been with either
    // UNSIGNALED, or UNSIGNALED_WITH_WAITERS.  Anything else is an indication
    // of either a bad pointer being passed, or corruption.
    if ((expected != UNSIGNALED) && (expected != UNSIGNALED_WITH_WAITERS)) {
      __builtin_trap();
    }
  }
}

bool sync_completion_signaled(sync_completion_t* completion) {
  return atomic_load_explicit(&completion->futex, memory_order_acquire) == SIGNALED;
}
