// 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/elf-psabi/sp.h>
#include <stddef.h>
#include <stdint.h>
#include <zircon/syscalls.h>

#include <runtime/thread.h>

// An zxr_thread_t starts its life JOINABLE.
// - If someone calls zxr_thread_join on it, it transitions to JOINED.
// - If someone calls zxr_thread_detach on it, it transitions to DETACHED.
// - When it begins exiting, the EXITING state is entered.
// - When it is no longer using its memory and handle resources, it transitions
//   to DONE.  If the thread was DETACHED prior to EXITING, this transition MAY
//   not happen.
// No other transitions occur.

enum {
  JOINABLE,
  DETACHED,
  JOINED,
  EXITING,
  DONE,
};

typedef struct {
  zxr_thread_entry_t entry;
  zx_handle_t handle;
  atomic_int state;
} zxr_internal_thread_t;

// zxr_thread_t should reserve enough size for our internal data.
_Static_assert(sizeof(zxr_thread_t) == sizeof(zxr_internal_thread_t),
               "Update zxr_thread_t size for this platform.");

static inline zxr_internal_thread_t* to_internal(zxr_thread_t* external) {
  return (zxr_internal_thread_t*)(external);
}

zx_status_t zxr_thread_destroy(zxr_thread_t* thread) {
  zx_handle_t handle = to_internal(thread)->handle;
  to_internal(thread)->handle = ZX_HANDLE_INVALID;
  return handle == ZX_HANDLE_INVALID ? ZX_OK : _zx_handle_close(handle);
}

// Put the thread into EXITING state.  Returns the previous state.
static int begin_exit(zxr_internal_thread_t* thread) {
  return atomic_exchange_explicit(&thread->state, EXITING, memory_order_release);
}

// Claim the thread as JOINED or DETACHED.  Returns true on success, which only
// happens if the previous state was JOINABLE.  Always returns the previous state.
static bool claim_thread(zxr_internal_thread_t* thread, int new_state, int* old_state) {
  *old_state = JOINABLE;
  return atomic_compare_exchange_strong_explicit(&thread->state, old_state, new_state,
                                                 memory_order_acq_rel, memory_order_acquire);
}

// Extract the handle from the thread structure.  This must only be called by the thread
// itself (i.e., this is not thread-safe).
static zx_handle_t take_handle(zxr_internal_thread_t* thread) {
  zx_handle_t tmp = thread->handle;
  thread->handle = ZX_HANDLE_INVALID;
  return tmp;
}

static _Noreturn void exit_non_detached(zxr_internal_thread_t* thread) {
  // As soon as thread->state has changed to to DONE, a caller of zxr_thread_join
  // might complete and deallocate the memory containing the thread descriptor.
  // Hence it's no longer safe to touch *thread or read anything out of it.
  // Therefore we must extract the thread handle before that transition
  // happens.
  zx_handle_t handle = take_handle(thread);

  // Wake the _zx_futex_wait in zxr_thread_join (below), and then die.
  // This has to be done with the special four-in-one vDSO call because
  // as soon as the state transitions to DONE, the joiner is free to unmap
  // our stack out from under us.  Note there is a benign race here still: if
  // the address is unmapped and our futex_wake fails, it's OK; if the memory
  // is reused for something else and our futex_wake tickles somebody
  // completely unrelated, well, that's why futex_wait can always have
  // spurious wakeups.
  _zx_futex_wake_handle_close_thread_exit(&thread->state, 1, DONE, handle);
  __builtin_trap();
}

static _Noreturn void thread_trampoline(uintptr_t ctx, uintptr_t arg) {
  zxr_internal_thread_t* thread = (zxr_internal_thread_t*)ctx;

  thread->entry((void*)arg);

  int old_state = begin_exit(thread);
  switch (old_state) {
    case JOINABLE:
      // Nobody's watching right now, but they might start watching as we
      // exit.  Just in case, behave as if we've been joined and wake the
      // futex on our way out.
    case JOINED:
      // Somebody loves us!  Or at least intends to inherit when we die.
      exit_non_detached(thread);
      break;
  }

  // Cannot be in DONE, EXITING, or DETACHED and reach here.  For DETACHED, it
  // is the responsibility of a higher layer to ensure this is not reached.
  __builtin_trap();
}

_Noreturn void zxr_thread_exit_unmap_if_detached(zxr_thread_t* thread, void (*if_detached)(void*),
                                                 void* if_detached_arg,

                                                 zx_handle_t vmar, uintptr_t addr, size_t len) {
  int old_state = begin_exit(to_internal(thread));
  switch (old_state) {
    case DETACHED: {
      (*if_detached)(if_detached_arg);
      zx_handle_t handle = take_handle(to_internal(thread));
      _zx_vmar_unmap_handle_close_thread_exit(vmar, addr, len, handle);
      break;
    }
    // See comments in thread_trampoline.
    case JOINABLE:
    case JOINED:
      exit_non_detached(to_internal(thread));
      break;
  }

  // Cannot be in DONE or the EXITING and reach here.
  __builtin_trap();
}

// Local implementation so libruntime does not depend on libc.
static size_t local_strlen(const char* s) {
  size_t len = 0;
  while (*s++ != '\0')
    ++len;
  return len;
}

static void initialize_thread(zxr_internal_thread_t* thread, zx_handle_t handle, bool detached) {
  *thread = (zxr_internal_thread_t){
      .handle = handle,
  };
  atomic_init(&thread->state, detached ? DETACHED : JOINABLE);
}

zx_status_t zxr_thread_create(zx_handle_t process, const char* name, bool detached,
                              zxr_thread_t* thread) {
  initialize_thread(to_internal(thread), ZX_HANDLE_INVALID, detached);
  if (name == NULL)
    name = "";
  size_t name_length = local_strlen(name) + 1;
  return _zx_thread_create(process, name, name_length, 0, &to_internal(thread)->handle);
}

zx_status_t zxr_thread_start(zxr_thread_t* thread, uintptr_t stack_addr, size_t stack_size,
                             zxr_thread_entry_t entry, void* arg) {
  to_internal(thread)->entry = entry;

  // compute the starting address of the stack
  uintptr_t sp = compute_initial_stack_pointer(stack_addr, stack_size);

  // kick off the new thread
  zx_status_t status = _zx_thread_start(to_internal(thread)->handle, (uintptr_t)thread_trampoline,
                                        sp, (uintptr_t)thread, (uintptr_t)arg);

  if (status != ZX_OK)
    zxr_thread_destroy(thread);
  return status;
}

static void wait_for_done(zxr_internal_thread_t* thread, int32_t old_state) {
  do {
    switch (_zx_futex_wait(&thread->state, old_state, ZX_HANDLE_INVALID, ZX_TIME_INFINITE)) {
      case ZX_ERR_BAD_STATE:  // Never blocked because it had changed.
      case ZX_OK:             // Woke up because it might have changed.
        old_state = atomic_load_explicit(&thread->state, memory_order_acquire);
        break;
      default:
        __builtin_trap();
    }
    // Wait until we reach the DONE state, even if we observe the
    // intermediate EXITING state.
  } while (old_state == JOINED || old_state == EXITING);

  if (old_state != DONE)
    __builtin_trap();
}

zx_status_t zxr_thread_join(zxr_thread_t* external_thread) {
  zxr_internal_thread_t* thread = to_internal(external_thread);

  int old_state;
  // Try to claim the join slot on this thread.
  if (claim_thread(thread, JOINED, &old_state)) {
    wait_for_done(thread, JOINED);
  } else {
    switch (old_state) {
      case JOINED:
      case DETACHED:
        return ZX_ERR_INVALID_ARGS;
      case EXITING:
        // Since it is undefined to call zxr_thread_join on a thread
        // that has already been detached or joined, we assume the state
        // prior to EXITING was JOINABLE, and act as if we had
        // successfully transitioned to JOINED.
        wait_for_done(thread, EXITING);
        __FALLTHROUGH;
      case DONE:
        break;
      default:
        __builtin_trap();
    }
  }

  // The thread has already closed its own handle.
  return ZX_OK;
}

zx_status_t zxr_thread_detach(zxr_thread_t* thread) {
  int old_state;
  // Try to claim the join slot on this thread on behalf of the thread.
  if (!claim_thread(to_internal(thread), DETACHED, &old_state)) {
    switch (old_state) {
      case DETACHED:
      case JOINED:
        return ZX_ERR_INVALID_ARGS;
      case EXITING: {
        // Since it is undefined behavior to call zxr_thread_detach on a
        // thread that has already been detached or joined, we assume
        // the state prior to EXITING was JOINABLE.  However, since the
        // thread is already shutting down, it is too late to tell it to
        // clean itself up.  Since the thread is still running, we cannot
        // just return ZX_ERR_BAD_STATE, which would suggest we couldn't detach and
        // the thread has already finished running.  Instead, we call join,
        // which will return soon due to the thread being actively shutting down,
        // and then return ZX_ERR_BAD_STATE to tell the caller that they
        // must manually perform any post-join work.
        zx_status_t ret = zxr_thread_join(thread);
        if (unlikely(ret != ZX_OK)) {
          if (unlikely(ret != ZX_ERR_INVALID_ARGS)) {
            __builtin_trap();
          }
          return ret;
        }
      }
        // Fall-through to DONE case.
        __FALLTHROUGH;
      case DONE:
        return ZX_ERR_BAD_STATE;
      default:
        __builtin_trap();
    }
  }

  return ZX_OK;
}

bool zxr_thread_detached(zxr_thread_t* thread) {
  int state = atomic_load_explicit(&to_internal(thread)->state, memory_order_acquire);
  return state == DETACHED;
}

zx_handle_t zxr_thread_get_handle(zxr_thread_t* thread) { return to_internal(thread)->handle; }

zx_status_t zxr_thread_adopt(zx_handle_t handle, zxr_thread_t* thread) {
  initialize_thread(to_internal(thread), handle, false);
  return handle == ZX_HANDLE_INVALID ? ZX_ERR_BAD_HANDLE : ZX_OK;
}
