// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <inttypes.h>
#include <lib/syscalls/forward.h>
#include <trace.h>
#include <zircon/types.h>

#include <object/futex_context.h>
#include <object/process_dispatcher.h>

#define LOCAL_TRACE 0

// zx_status_t zx_futex_wait
zx_status_t sys_futex_wait(user_in_ptr<const zx_futex_t> value_ptr, zx_futex_t current_value,
                           zx_handle_t new_futex_owner, zx_time_t deadline) {
  LTRACEF("futex %p current %d\n", value_ptr.get(), current_value);

  ProcessDispatcher* dispatcher = ThreadDispatcher::GetCurrent()->process();
  const TimerSlack slack = dispatcher->GetTimerSlackPolicy();
  const Deadline slackDeadline(deadline, slack);

  return dispatcher->futex_context().FutexWait(value_ptr, current_value, new_futex_owner,
                                               slackDeadline);
}

// zx_status_t zx_futex_wake
zx_status_t sys_futex_wake(user_in_ptr<const zx_futex_t> value_ptr, uint32_t count) {
  LTRACEF("futex %p count %" PRIu32 "\n", value_ptr.get(), count);

  return ProcessDispatcher::GetCurrent()->futex_context().FutexWake(
      value_ptr, count, FutexContext::OwnerAction::RELEASE);
}

// zx_status_t zx_futex_requeue
zx_status_t sys_futex_requeue(user_in_ptr<const zx_futex_t> wake_ptr, uint32_t wake_count,
                              zx_futex_t current_value, user_in_ptr<const zx_futex_t> requeue_ptr,
                              uint32_t requeue_count, zx_handle_t requeue_owner) {
  LTRACEF("futex %p wake_count %" PRIu32
          "current_value %d "
          "requeue_futex %p requeue_count %" PRIu32 "\n",
          wake_ptr.get(), wake_count, current_value, requeue_ptr.get(), requeue_count);

  return ProcessDispatcher::GetCurrent()->futex_context().FutexRequeue(
      wake_ptr, wake_count, current_value, FutexContext::OwnerAction::RELEASE, requeue_ptr,
      requeue_count, requeue_owner);
}

// zx_status_t zx_futex_wake_single_owner
zx_status_t sys_futex_wake_single_owner(user_in_ptr<const zx_futex_t> value_ptr) {
  LTRACEF("futex %p\n", value_ptr.get());

  return ProcessDispatcher::GetCurrent()->futex_context().FutexWake(
      value_ptr, 1u, FutexContext::OwnerAction::ASSIGN_WOKEN);
}

// zx_status_t zx_futex_requeue_single_owner
zx_status_t sys_futex_requeue_single_owner(user_in_ptr<const zx_futex_t> wake_ptr,
                                           zx_futex_t current_value,
                                           user_in_ptr<const zx_futex_t> requeue_ptr,
                                           uint32_t requeue_count, zx_handle_t requeue_owner) {
  LTRACEF("futex %p current_value %d requeue_futex %p requeue_count %" PRIu32 "\n", wake_ptr.get(),
          current_value, requeue_ptr.get(), requeue_count);

  return ProcessDispatcher::GetCurrent()->futex_context().FutexRequeue(
      wake_ptr, 1u, current_value, FutexContext::OwnerAction::ASSIGN_WOKEN, requeue_ptr,
      requeue_count, requeue_owner);
}

zx_status_t sys_futex_get_owner(user_in_ptr<const zx_futex_t> value_ptr,
                                user_out_ptr<zx_koid_t> koid) {
  LTRACEF("futex %p\n", value_ptr.get());
  return ProcessDispatcher::GetCurrent()->futex_context().FutexGetOwner(value_ptr, koid);
}
