/*
   Copyright (c) 2011, 2014 mingw-w64 project
   Copyright (c) 2015 Intel Corporation

   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 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.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <malloc.h>
#include <stdio.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define WINPTHREAD_MUTEX_DECL WINPTHREAD_API

/* public header files */
#include "pthread.h"
/* internal header files */
#include "misc.h"

/**
 * Reference:
 *
 * pthread_mutex_init(), pthread_mutex_destroy():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutex_destroy.html>
 *
 * pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutex_lock.html>
 *
 * pthread_mutex_timedlock(), pthread_mutex_clocklock():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutex_clocklock.html>
 *
 * pthread_mutex_getprioceiling(), pthread_mutex_setprioceiling():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutex_getprioceiling.html>
 *
 * pthread_mutex_consistent():
 * <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutex_consistent.html>
 *
 * pthread_mutexattr_init(), pthread_mutexattr_destroy():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutexattr_destroy.html>
 *
 * pthread_mutexattr_gettype(), pthread_mutexattr_settype():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutexattr_gettype.html>
 *
 * pthread_mutexattr_getpshared(), pthread_mutexattr_setpshared():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutexattr_getpshared.html>
 *
 * pthread_mutexattr_getprotocol(), pthread_mutexattr_setprotocol():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutexattr_getprotocol.html>
 *
 * pthread_mutexattr_getprioceiling(), pthread_mutexattr_setprioceiling():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutexattr_getprioceiling.html>
 *
 * pthread_mutexattr_getrobust(), pthread_mutexattr_setrobust():
 *  <https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutexattr_getrobust.html>
 *
 * The following functions are not implemented:
 *
 * - pthread_mutex_clocklock()
 * - pthread_mutex_getprioceiling()
 * - pthread_mutex_setprioceiling()
 * - pthread_mutex_consistent()
 * - pthread_mutexattr_getrobust()
 * - pthread_mutexattr_setrobust()
 */

typedef enum {
  Unlocked,        /* Not locked. */
  Locked,          /* Locked but without waiters. */
  Waiting,         /* Locked, may have waiters. */
} mutex_state_t;

typedef enum {
  Normal,
  Errorcheck,
  Recursive,
} mutex_type_t;

/* The heap-allocated part of a mutex. */
typedef struct {
  mutex_state_t state;
  mutex_type_t type;
  HANDLE event;       /* Auto-reset event, or NULL if not yet allocated. */
  unsigned rec_lock;  /* For recursive mutexes, the number of times the
                         mutex has been locked in excess by the same thread. */
  volatile DWORD owner;  /* For recursive and error-checking mutexes, the
                            ID of the owning thread if the mutex is locked. */
} mutex_impl_t;

/**
 * Evaluates to non-zero if `m` is a static initializer for `pthread_mutex_t`:
 *
 * PTHREAD_DEFAULT_MUTEX_INITIALIZER:    -1
 * PTHREAD_NORMAL_MUTEX_INITIALIZER:     -1
 * PTHREAD_ERRORCHECK_MUTEX_INITIALIZER: -2
 * PTHREAD_RECURSIVE_MUTEX_INITIALIZER:  -3
 */
#define STATIC_MUTEX_INITIALIZER(m) ((uintptr_t)(m) >= (uintptr_t)-3)

/* Create and return the implementation part of a mutex from a static
   initialiser. Return NULL on out-of-memory error. */
static WINPTHREADS_ATTRIBUTE((noinline)) mutex_impl_t *mutex_impl_init(pthread_mutex_t *m, mutex_impl_t *mi)
{
  mutex_impl_t *new_mi = malloc(sizeof(mutex_impl_t));
  if (new_mi == NULL)
    return NULL;
  new_mi->state = Unlocked;
  new_mi->type = (mi == (void *)PTHREAD_RECURSIVE_MUTEX_INITIALIZER ? Recursive
                  : mi == (void *)PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ? Errorcheck
                  : Normal);
  new_mi->event = NULL;
  new_mi->rec_lock = 0;
  new_mi->owner = (DWORD)-1;
  if (InterlockedCompareExchangePointer((PVOID volatile *)m, new_mi, mi) == mi) {
    return new_mi;
  } else {
    /* Someone created the struct before us. */
    free(new_mi);
    return (mutex_impl_t *)*m;
  }
}

/* Return the implementation part of a mutex, creating it if necessary.
   Return NULL on out-of-memory error. */
static WINPTHREADS_INLINE mutex_impl_t *mutex_impl(pthread_mutex_t *m)
{
  mutex_impl_t *mi = (mutex_impl_t *)*m;
  if (STATIC_MUTEX_INITIALIZER(mi)) {
    return mutex_impl_init(m, mi);
  } else {
    /* mi cannot be null here; avoid a test in the fast path. */
    if (mi == NULL)
      UNREACHABLE();
    return mi;
  }
}

/* Lock a mutex. Give up after 'timeout' ms (with ETIMEDOUT),
   or never if timeout=INFINITE. */
static WINPTHREADS_INLINE int pthread_mutex_lock_intern(pthread_mutex_t *m, DWORD timeout)
{
  mutex_impl_t *mi = mutex_impl(m);
  if (mi == NULL)
    return ENOMEM;
  mutex_state_t old_state = InterlockedExchange((long *)&mi->state, Locked);
  if (unlikely(old_state != Unlocked)) {
    /* The mutex is already locked. */

    if (mi->type != Normal) {
      /* Recursive or Errorcheck */
      if (mi->owner == GetCurrentThreadId()) {
        /* FIXME: A recursive mutex should not need two atomic ops when locking
           recursively.  We could rewrite by doing compare-and-swap instead of
           test-and-set the first time, but it would lead to more code
           duplication and add a conditional branch to the critical path. */
        InterlockedCompareExchange((long *)&mi->state, old_state, Locked);
        if (mi->type == Recursive) {
          mi->rec_lock++;
          return 0;
        } else {
          /* type == Errorcheck */
          return EDEADLK;
        }
      }
    }

    /* Make sure there is an event object on which to wait. */
    if (mi->event == NULL) {
      /* Make an auto-reset event object. */
      HANDLE ev = CreateEvent(NULL, FALSE, FALSE, NULL);
      if (ev == NULL) {
        switch (GetLastError()) {
        case ERROR_ACCESS_DENIED:
          return EPERM;
        default:
          return ENOMEM;    /* Probably accurate enough. */
        }
      }
      if (InterlockedCompareExchangePointer(&mi->event, ev, NULL) != NULL) {
        /* Someone created the event before us. */
        CloseHandle(ev);
      }
    }

    /* At this point, mi->event is non-NULL. */

    while (InterlockedExchange((long *)&mi->state, Waiting) != Unlocked) {
      /* For timed locking attempts, it is possible (although unlikely)
         that we are woken up but someone else grabs the lock before us,
         and we have to go back to sleep again. In that case, the total
         wait may be longer than expected. */
      unsigned r = _pthread_wait_for_single_object(mi->event, timeout);
      switch (r) {
      case WAIT_TIMEOUT:
        return ETIMEDOUT;
      case WAIT_OBJECT_0:
        break;
      default:
        return EINVAL;
      }
    }
  }

  if (mi->type != Normal)
    mi->owner = GetCurrentThreadId();

  return 0;
}

int pthread_mutex_lock(pthread_mutex_t *m)
{
  return pthread_mutex_lock_intern (m, INFINITE);
}

int pthread_mutex_timedlock64(pthread_mutex_t *m, const struct _timespec64 *ts)
{
  unsigned long long patience;
  if (ts != NULL) {
    unsigned long long end = _pthread_time_in_ms_from_timespec(ts);
    unsigned long long now = _pthread_time_in_ms();
    patience = end > now ? end - now : 0;
    if (patience > 0xffffffff)
      patience = INFINITE;
  } else {
    patience = INFINITE;
  }
  return pthread_mutex_lock_intern(m, patience);
}

int pthread_mutex_timedlock32(pthread_mutex_t *m, const struct _timespec32 *ts)
{
  struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec};
  return pthread_mutex_timedlock64 (m, &ts64);
}

int pthread_mutex_unlock(pthread_mutex_t *m)
{
  /* Here m might an initialiser of an error-checking or recursive mutex, in
     which case the behaviour is well-defined, so we can't skip this check. */
  mutex_impl_t *mi = mutex_impl(m);
  if (mi == NULL)
    return ENOMEM;

  if (unlikely(mi->type != Normal)) {
    if (mi->state == Unlocked)
      return EPERM;
    if (mi->owner != GetCurrentThreadId())
      return EPERM;
    if (mi->rec_lock > 0) {
      mi->rec_lock--;
      return 0;
    }
    mi->owner = (DWORD)-1;
  }
  if (unlikely(InterlockedExchange((long *)&mi->state, Unlocked) == Waiting)) {
    if (!SetEvent(mi->event))
      return EPERM;
  }
  return 0;
}

int pthread_mutex_trylock(pthread_mutex_t *m)
{
  mutex_impl_t *mi = mutex_impl(m);
  if (mi == NULL)
    return ENOMEM;

  if (InterlockedCompareExchange((long *)&mi->state, Locked, Unlocked) == Unlocked) {
    if (mi->type != Normal)
      mi->owner = GetCurrentThreadId();
    return 0;
  } else {
    if (mi->type == Recursive && mi->owner == GetCurrentThreadId()) {
      mi->rec_lock++;
      return 0;
    }
    return EBUSY;
  }
}

int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a)
{
  pthread_mutex_t init = PTHREAD_MUTEX_INITIALIZER;
  if (a != NULL) {
    int pshared;
    if (pthread_mutexattr_getpshared(a, &pshared) == 0 && pshared == PTHREAD_PROCESS_SHARED)
      return ENOSYS;

    int type;
    if (pthread_mutexattr_gettype(a, &type) == 0) {
      switch (type) {
      case PTHREAD_MUTEX_ERRORCHECK:
        init = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER;
        break;
      case PTHREAD_MUTEX_RECURSIVE:
        init = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
        break;
      default:
        init = PTHREAD_MUTEX_INITIALIZER;
        break;
      }
    }
  }
  *m = init;
  return 0;
}

int pthread_mutex_destroy(pthread_mutex_t *m)
{
  mutex_impl_t *mi = (mutex_impl_t *)*m;
  if (!STATIC_MUTEX_INITIALIZER(mi)) {
    if (mi->event != NULL)
      CloseHandle(mi->event);
    free(mi);
    /* Sabotage attempts to re-use the mutex before initialising it again. */
    *m = (pthread_mutex_t)NULL;
  }

  return 0;
}

int pthread_mutexattr_init(pthread_mutexattr_t *a)
{
  *a = PTHREAD_MUTEX_NORMAL | (PTHREAD_PROCESS_PRIVATE << 3);
  return 0;
}

int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
{
  if (!a)
    return EINVAL;

  return 0;
}

int pthread_mutexattr_gettype(const pthread_mutexattr_t *a, int *type)
{
  if (!a || !type)
    return EINVAL;

  *type = *a & 3;

  return 0;
}

int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
{
  if (!a)
    return EINVAL;

  if (type != PTHREAD_MUTEX_NORMAL && type != PTHREAD_MUTEX_RECURSIVE && type != PTHREAD_MUTEX_ERRORCHECK)
    return EINVAL;

  *a &= ~3;
  *a |= type;

  return 0;
}

int pthread_mutexattr_getpshared(const pthread_mutexattr_t *a, int *type)
{
  if (!a || !type)
    return EINVAL;

  *type = (*a & 4 ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE);

  return 0;
}

int pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int type)
{
  int r = 0;

  if (!a)
    return EINVAL;

  if (type != PTHREAD_PROCESS_SHARED && type != PTHREAD_PROCESS_PRIVATE)
    return EINVAL;

  if (type == PTHREAD_PROCESS_SHARED) {
    type = PTHREAD_PROCESS_PRIVATE;
    r = ENOSYS;
  }

  type = (type == PTHREAD_PROCESS_SHARED ? 4 : 0);

  *a &= ~4;
  *a |= type;

  return r;
}

int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *a, int *type)
{
  *type = *a & (8 + 16);
  return 0;
}

int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type)
{
  if ((type & (8 + 16)) != 8 + 16)
    return EINVAL;

  *a &= ~(8 + 16);
  *a |= type;

  return 0;
}

int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *a, int *prio)
{
  *prio = *a / PTHREAD_PRIO_MULT;
  return 0;
}

int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio)
{
  *a &= (PTHREAD_PRIO_MULT - 1);
  *a += prio * PTHREAD_PRIO_MULT;

  return 0;
}
