/*
   Copyright (c) 2011, 2014, 2026 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 <limits.h>
#include <stdlib.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()
 */

/**
 * Forward declaration; see definition below.
 */
typedef union WinpthreadsMutex WinpthreadsMutex;

/**
 * Forward declaration; see definition below.
 */
typedef union WinpthreadsMutexAttributes WinpthreadsMutexAttributes;

/**
 * Mutex type-specific "init" routine.
 */
typedef int (* FuncMutexInit) (WinpthreadsMutex **, const WinpthreadsMutexAttributes *);

/**
 * Mutex type-specific "destroy" routine.
 */
typedef void (* FuncMutexDestroy) (WinpthreadsMutex *);

/**
 * Mutex type-specific "lock" routine.
 *
 * If second argument is `NULL`, this function will block indefinitely.
 */
typedef int (* FuncMutexLock) (WinpthreadsMutex *, const struct _timespec64 *);

/**
 * Mutex type-specific "try lock" routine.
 *
 * If second argument is `TRUE`, this function will only succeed if mutex is
 * not owned by any thread, including the calling thread.
 */
typedef int (* FuncMutexTryLock) (WinpthreadsMutex *, BOOL);

/**
 * Mutex type-specific "unlock" routine.
 */
typedef int (* FuncMutexUnlock) (WinpthreadsMutex *);

/**
 * Implementation for specific Mutex type.
 */
typedef struct {
  FuncMutexInit Init;
  FuncMutexDestroy Destroy;
  FuncMutexLock Lock;
  FuncMutexTryLock TryLock;
  FuncMutexUnlock Unlock;
} WinpthreadsMutexVtable;

/**
 * Union stored in `pthread_mutexattr_t` objects.
 */
union WinpthreadsMutexAttributes {
  pthread_mutexattr_t Value;
  struct {
    /**
     * Can be one of the following values:
     *
     * - PTHREAD_MUTEX_NORMAL
     * - PTHREAD_MUTEX_ERRORCHECK
     * - PTHREAD_MUTEX_RECURSIVE
     */
    int Type            : 4;
    /**
     * Zero for `PTHREAD_PROCESS_PRIVATE` and non-zero for
     * `PTHREAD_PROCESS_SHARED`.
     *
     * Currently, winpthreads only supports `PTHREAD_PROCESS_PRIVATE`.
     */
    int Shared          : 1;
    int Reserved        : 3;
    /**
     * Can be one of the following values:
     *
     * - PTHREAD_PRIO_NONE
     * - PTHREAD_PRIO_INHERIT
     * - PTHREAD_PRIO_PROTECT
     *
     * Currently, winpthreads does not implement POSIX realtime extensions.
     * As such, the only supported value is `PTHREAD_PRIO_NONE`.
     */
    int Protocol        : 8;
    /**
     * Can be any valid `THREAD_PRIORITY_*` value.
     *
     * Only has effect when `Protocol` is `PTHREAD_PRIO_INHERIT` or
     * `PTHREAD_PRIO_PROTECT`, which are not currently supported.
     */
    int PriorityCeiling : 8;
#define WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC 0x67
    /**
     * Must be `WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC`.
     *
     * If needed, these bits may be used for future extensions.
     */
    int Magic           : 8;
  } Attributes;
};

WINPTHREADS_STATIC_ASSERT (sizeof ((WinpthreadsMutexAttributes) {}.Attributes) == sizeof (pthread_mutexattr_t), "");

/**
 * Expands into an expression of type `WinpthreadsMutexAttributes`
 * corresponding to the default mutex attributes.
 */
#define WINPTHREADS_MUTEX_ATTRIBUTES_DEFAULT ((WinpthreadsMutexAttributes) { \
    .Attributes.Type            = PTHREAD_MUTEX_NORMAL,                      \
    .Attributes.Shared          = PTHREAD_PROCESS_PRIVATE,                   \
    .Attributes.Reserved        = 0,                                         \
    .Attributes.Protocol        = PTHREAD_PRIO_NONE,                         \
    .Attributes.PriorityCeiling = THREAD_PRIORITY_NORMAL,                    \
    .Attributes.Magic           = WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC         \
  })

#define THREAD_ID_NO_OWNER ((DWORD) -1)

/**
 * Mutex lock states.
 */
typedef enum {
  /**
   * Mutex is unlocked.
   */
  Unlocked,
  /**
   * Mutex is locked.
   *
   * This state inicates that there are no blocked threads waiting for
   * the mutex to be released.
   *
   * While in this state, if any thread blocks waiting for the mutex to be
   * released, the lock state will change to `LockedWithBlocking`.
   */
  Locked,
  /**
   * Mutex is locked.
   *
   * This state indicates that there can be one or more blocked threads waiting
   * for the mutex to be released.
   */
  LockedWithBlocking,
} WinpthreadsMutexLockState;

/**
 * Common base for `Winpthreads{Type}Mutex` structures defined below.
 */
typedef struct {
  const WinpthreadsMutexVtable *Vtable;
} WinpthreadsMutexBase;

/**
 * Data specific to Normal Mutex implementation.
 */
typedef struct {
  WinpthreadsMutexBase Base;
  /**
   * Auto-reset event.
   *
   * Normal Mutexes are implemented using auto-reset events.
   */
  HANDLE Event;
  /**
   * One of `WinpthreadsMutexLockState` values.
   */
  LONG LockState;
} WinpthreadsNormalMutex;

WINPTHREADS_STATIC_ASSERT (offsetof (WinpthreadsMutexBase, Vtable) == offsetof (WinpthreadsNormalMutex, Base.Vtable), "");

/**
 * Data specific to Error Checking Mutex implementation.
 */
typedef struct {
  WinpthreadsMutexBase Base;
  /**
   * Auto-reset event.
   *
   * Error Checking Mutexes are implemented using auto-reset events.
   */
  HANDLE Event;
  /**
   * One of `WinpthreadsMutexLockState` values.
   */
  LONG LockState;
  /**
   * ID of the thread owning the mutex.
   * If mutex has no owner, this field is set to `THREAD_ID_NO_OWNER`.
   */
  DWORD Owner;
} WinpthreadsErrorCheckMutex;

WINPTHREADS_STATIC_ASSERT (offsetof (WinpthreadsMutexBase, Vtable) == offsetof (WinpthreadsErrorCheckMutex, Base.Vtable), "");

/**
 * Data specific to Recursive Mutex implementation.
 */
typedef struct {
  WinpthreadsMutexBase Base;
  /**
   * Auto-reset event.
   *
   * Recursive Mutexes are implemented using auto-reset events.
   */
  HANDLE Event;
  /**
   * One of `WinpthreadsMutexLockState` values.
   */
  LONG LockState;
  /**
   * ID of the thread owning the mutex.
   * If mutex has no owner, this field is set to `THREAD_ID_NO_OWNER`.
   */
  DWORD Owner;
  /**
   * Recursive lock count.
   *
   * When a thread locks the mutex, this value is incremented by 1.
   * When a thread unlocks the mutex, this value is decremented by 1.
   *
   * A thread owns the mutes as long as lock count is greater than zero;
   * once lock count reaches zero, the owning thread releases the ownership of
   * the mutex.
   */
  unsigned int LockCount;
} WinpthreadsRecursiveMutex;

WINPTHREADS_STATIC_ASSERT (offsetof (WinpthreadsMutexBase, Vtable) == offsetof (WinpthreadsRecursiveMutex, Base.Vtable), "");

/**
 * Union pointed to by `pthread_mutex_t` objects.
 */
union WinpthreadsMutex {
  WinpthreadsMutexBase       Base;
  WinpthreadsNormalMutex     NormalMutex;
  WinpthreadsErrorCheckMutex ErrorCheckMutex;
  WinpthreadsRecursiveMutex  RecursiveMutex;
};

WINPTHREADS_STATIC_ASSERT (offsetof (WinpthreadsMutexBase, Vtable) == offsetof (WinpthreadsMutex, Base.Vtable), "");

/*******************************************************************************
 * Common helper functions.
 */

/**
 * Wait until `handle` becomes signaled or timeout specified by `waitUntil`
 * has expired. If `waitUntil` is `NULL`, this function waits indefinitely until
 * `handle` becomes signaled.
 *
 * Returns zero on success and an error-code on failure.
 */
static WINPTHREADS_INLINE int WinpthreadsTimedWait (HANDLE handle, LONG *lockState, const struct _timespec64 *waitUntil) {
  unsigned __int64 waitStartTime = 0;
  unsigned __int64 waitEndTime   = 0;
  unsigned __int64 waitTimeout   = INFINITE;

  if (waitUntil != NULL) {
    waitStartTime = _pthread_time_in_ms ();
    waitEndTime   = _pthread_time_in_ms_from_timespec (waitUntil);
    waitTimeout   = 0;

    if (waitStartTime < waitEndTime) {
      waitTimeout = waitEndTime - waitStartTime;

      if (waitTimeout > INFINITE) {
        waitTimeout = INFINITE;
      }
    }
  }

  /**
   * Setting lock state to `LockedWithBlocking` prevents the fast lock path
   * (`lockState` cannot be set to `Locked`) and it causes
   * `Winpthreads*MutexUnlock` functions to signal `handle`.
   */
  LONG oldLockState = InterlockedExchange (lockState, LockedWithBlocking);

  while (oldLockState != Unlocked) {
    switch (_pthread_wait_for_single_object (handle, (DWORD) waitTimeout)) {
      /**
       * `handle` was in signaled state (unlocked) or it became signaled
       * within `waitTimeout`.
       */
      case WAIT_OBJECT_0:
        break;
      /**
       * `handle` was not signaled (unlocked) before `waitTimeout` expired.
       */
      case WAIT_TIMEOUT:
        return ETIMEDOUT;
      default:
        return EINVAL;
    }

    /**
     * There is a small chance that another thread grabs the lock faster
     * than we do; lock state is updated before wait handle is signaled.
     */
    oldLockState = InterlockedExchange (lockState, LockedWithBlocking);

    if (likely (oldLockState == Unlocked)) {
      break;
    }

    /**
     * Update `waitTimeout`, if not `INFINITE`.
     */
    if (waitTimeout != INFINITE) {
      waitStartTime = _pthread_time_in_ms ();

      if (waitStartTime >= waitEndTime) {
        return ETIMEDOUT;
      }

      waitTimeout = waitEndTime - waitStartTime;
    }
  }

  return 0;
}

/*******************************************************************************
 * Normal Mutex (PTHREAD_MUTEX_NORMAL) implementation.
 *
 * Normal Mutexes have the following properties:
 *
 * - Attempt to relock a mutex that is already owned by the calling thread
 *   results in a dead lock.
 * - Attempt to unlock a mutex that is not owned by the calling thread is UB.
 * - Attempt to unlock an unlocked mutex is UB.
 *
 * Historically, in winpthreads, Normal Mutexes ignore ownership,
 * which results in the following well-defined behavior:
 *
 * - Calls to `pthread_mutex_unlock` always succeed; and
 * - A thread can unlock mutex owned by another thread.
 */

static int WinpthreadsNormalMutexInit (WinpthreadsMutex **wMutex, const WinpthreadsMutexAttributes *wMutexAttr) {
  WinpthreadsNormalMutex *mutex = malloc (sizeof (WinpthreadsNormalMutex));

  /**
   * The pthread_mutex_init() function shall fail if:
   *
   * [ENOMEM]
   *   Insufficient memory exists to initialize the mutex.
   */
  if (mutex == NULL) {
    return ENOMEM;
  }

  mutex->Event = CreateEventW (NULL, FALSE, FALSE, NULL);

  /**
   * The pthread_mutex_init() function shall fail if:
   *
   * [EAGAIN]
   *   The system lacked the necessary resources (other than memory) to
   *   initialize another mutex.
   */
  if (mutex->Event == NULL) {
    free (mutex);
    return EAGAIN;
  }

  mutex->LockState = Unlocked;
  *wMutex = (WinpthreadsMutex *) mutex;

  return 0;
  UNREFERENCED_PARAMETER (wMutexAttr);
}

static void WinpthreadsNormalMutexDestroy (WinpthreadsMutex *wMutex) {
  WinpthreadsNormalMutex *mutex = &wMutex->NormalMutex;
  HANDLE event = InterlockedExchangePointer ((void **) &mutex->Event, NULL);

  if (event != NULL) {
    CloseHandle (event);
  }

  free (mutex);
}

static int WinpthreadsNormalMutexLock (WinpthreadsMutex *wMutex, const struct _timespec64 *waitUntil) {
  WinpthreadsNormalMutex *mutex = &wMutex->NormalMutex;

  /**
   * Try the fast path.
   */
  if (InterlockedCompareExchange (&mutex->LockState, Locked, Unlocked) == Unlocked) {
    return 0;
  }

  return WinpthreadsTimedWait (mutex->Event, &mutex->LockState, waitUntil);
}

static int WinpthreadsNormalMutexTryLock (WinpthreadsMutex *wMutex, BOOL exclusiveLock) {
  WinpthreadsNormalMutex *mutex = &wMutex->NormalMutex;

  if (InterlockedCompareExchange (&mutex->LockState, Locked, Unlocked) != Unlocked) {
    return EBUSY;
  }

  return 0;
  UNREFERENCED_PARAMETER (exclusiveLock);
}

static int WinpthreadsNormalMutexUnlock (WinpthreadsMutex *wMutex) {
  WinpthreadsNormalMutex *mutex = &wMutex->NormalMutex;

  /**
   * If `mutex->LockState` is `LockedWithBlocking`, then some other thread is
   * waiting for `mutex->Event` to become signaled.
   */
  if (InterlockedExchange (&mutex->LockState, Unlocked) == LockedWithBlocking) {
    if (!SetEvent (mutex->Event)) {
      return EINVAL;
    }
  }

  return 0;
}

static const WinpthreadsMutexVtable WinpthreadsNormalMutexVtable = {
  .Init    = WinpthreadsNormalMutexInit,
  .Destroy = WinpthreadsNormalMutexDestroy,
  .Lock    = WinpthreadsNormalMutexLock,
  .TryLock = WinpthreadsNormalMutexTryLock,
  .Unlock  = WinpthreadsNormalMutexUnlock,
};

/*******************************************************************************
 * Error Checking Mutex (PTHREAD_MUTEX_ERRORCHECK) implementation.
 *
 * Error Checking Mutexes have the following properties:
 *
 * - Attempt to relock a mutex that is already owned by the calling thread
 *   fails with EDEADLK.
 * - Attempt to unlock a mutex that is not owned by the calling thread fails
 *   with EPERM.
 * - Attempt to unlock an unlocked mutex fails with EPERM.
 */

static int WinpthreadsErrorCheckMutexInit (WinpthreadsMutex **wMutex, const WinpthreadsMutexAttributes *wMutexAttr) {
  WinpthreadsErrorCheckMutex *mutex = malloc (sizeof (WinpthreadsErrorCheckMutex));

  /**
   * The pthread_mutex_init() function shall fail if:
   *
   * [ENOMEM]
   *   Insufficient memory exists to initialize the mutex.
   */
  if (mutex == NULL) {
    return ENOMEM;
  }

  mutex->Event = CreateEventW (NULL, FALSE, FALSE, NULL);

  /**
   * The pthread_mutex_init() function shall fail if:
   *
   * [EAGAIN]
   *   The system lacked the necessary resources (other than memory) to
   *   initialize another mutex.
   */
  if (mutex->Event == NULL) {
    free (mutex);
    return EAGAIN;
  }

  mutex->LockState = Unlocked;
  mutex->Owner     = THREAD_ID_NO_OWNER;

  *wMutex = (WinpthreadsMutex *) mutex;

  return 0;
  UNREFERENCED_PARAMETER (wMutexAttr);
}

static void WinpthreadsErrorCheckMutexDestroy (WinpthreadsMutex *wMutex) {
  WinpthreadsErrorCheckMutex *mutex = &wMutex->ErrorCheckMutex;
  HANDLE event = InterlockedExchangePointer ((void **) &mutex->Event, NULL);

  if (event != NULL) {
    CloseHandle (event);
  }

  free (mutex);
}

static int WinpthreadsErrorCheckMutexLock (WinpthreadsMutex *wMutex, const struct _timespec64 *waitUntil) {
  WinpthreadsErrorCheckMutex *mutex = &wMutex->ErrorCheckMutex;

  DWORD threadId = GetCurrentThreadId ();

  if (mutex->Owner == threadId) {
    return EDEADLK;
  }

  /**
   * Try the fast path.
   */
  if (InterlockedCompareExchange (&mutex->LockState, Locked, Unlocked) == Unlocked) {
    goto done;
  }

  int error_code = WinpthreadsTimedWait (mutex->Event, &mutex->LockState, waitUntil);

  if (error_code) {
    return error_code;
  }

done:
  mutex->Owner = threadId;

  return 0;
}

static int WinpthreadsErrorCheckMutexTryLock (WinpthreadsMutex *wMutex, BOOL exclusiveLock) {
  WinpthreadsErrorCheckMutex *mutex = &wMutex->ErrorCheckMutex;

  if (InterlockedCompareExchange (&mutex->LockState, Locked, Unlocked) != Unlocked) {
    return EBUSY;
  }

  mutex->Owner = GetCurrentThreadId ();

  return 0;
  UNREFERENCED_PARAMETER (exclusiveLock);
}

static int WinpthreadsErrorCheckMutexUnlock (WinpthreadsMutex *wMutex) {
  WinpthreadsErrorCheckMutex *mutex = &wMutex->ErrorCheckMutex;

  LONG threadId = (LONG) GetCurrentThreadId ();

  if (InterlockedCompareExchange ((LONG *) &mutex->Owner, (LONG) THREAD_ID_NO_OWNER, threadId) != threadId) {
    return EPERM;
  }

  /**
   * If `mutex->LockState` is `LockedWithBlocking`, then some other thread is
   * waiting for `mutex->Event` to become signaled.
   */
  if (InterlockedExchange (&mutex->LockState, Unlocked) == LockedWithBlocking) {
    if (!SetEvent (mutex->Event)) {
      return EINVAL;
    }
  }

  return 0;
}

static const WinpthreadsMutexVtable WinpthreadsErrorCheckMutexVtable = {
  .Init    = WinpthreadsErrorCheckMutexInit,
  .Destroy = WinpthreadsErrorCheckMutexDestroy,
  .Lock    = WinpthreadsErrorCheckMutexLock,
  .TryLock = WinpthreadsErrorCheckMutexTryLock,
  .Unlock  = WinpthreadsErrorCheckMutexUnlock,
};

/*******************************************************************************
 * Recursive Mutex (PTHREAD_MUTEX_RECURSIVE) implementation.
 *
 * Recursive Mutexes have the following properties:
 *
 * - Attempt to relock a mutex that is already owned by the calling thread
 *   succeeds and increases recursive lock count.
 * - Attempt to unlock a mutex that is not owned by the calling thread fails
 *   with EPERM.
 * - Attempt to unlock an unlocked mutex fails with EPERM.
 */

static int WinpthreadsRecursiveMutexInit (WinpthreadsMutex **wMutex, const WinpthreadsMutexAttributes *wMutexAttr) {
  WinpthreadsRecursiveMutex *mutex = malloc (sizeof (WinpthreadsRecursiveMutex));

  /**
   * The pthread_mutex_init() function shall fail if:
   *
   * [ENOMEM]
   *   Insufficient memory exists to initialize the mutex.
   */
  if (mutex == NULL) {
    return ENOMEM;
  }

  mutex->Event = CreateEventW (NULL, FALSE, FALSE, NULL);

  /**
   * The pthread_mutex_init() function shall fail if:
   *
   * [EAGAIN]
   *   The system lacked the necessary resources (other than memory) to
   *   initialize another mutex.
   */
  if (mutex->Event == NULL) {
    free (mutex);
    return EAGAIN;
  }

  mutex->LockState = Unlocked;
  mutex->Owner     = THREAD_ID_NO_OWNER;
  mutex->LockCount = 0;

  *wMutex = (WinpthreadsMutex *) mutex;

  return 0;
  UNREFERENCED_PARAMETER (wMutexAttr);
}

static void WinpthreadsRecursiveMutexDestroy (WinpthreadsMutex *wMutex) {
  WinpthreadsRecursiveMutex *mutex = &wMutex->RecursiveMutex;
  HANDLE event = InterlockedExchangePointer ((void **) &mutex->Event, NULL);

  if (event != NULL) {
    CloseHandle (event);
  }

  free (mutex);
}

static int WinpthreadsRecursiveMutexLock (WinpthreadsMutex *wMutex, const struct _timespec64 *waitUntil) {
  WinpthreadsRecursiveMutex *mutex = &wMutex->RecursiveMutex;

  DWORD threadId = GetCurrentThreadId ();

  /**
   * If calling thread already owns the mutex, simply increment the lock count.
   */
  if (mutex->Owner == threadId) {
    if (unlikely (mutex->LockCount == UINT_MAX)) {
      return EAGAIN;
    }

    mutex->LockCount++;
    return 0;
  }

  /**
   * Try the fast path.
   */
  if (InterlockedCompareExchange (&mutex->LockState, Locked, Unlocked) == Unlocked) {
    goto done;
  }

  int error_code = WinpthreadsTimedWait (mutex->Event, &mutex->LockState, waitUntil);

  if (error_code) {
    return error_code;
  }

done:
  mutex->Owner = threadId;
  mutex->LockCount = 1;

  return 0;
}

static int WinpthreadsRecursiveMutexTryLock (WinpthreadsMutex *wMutex, BOOL exclusiveLock) {
  WinpthreadsRecursiveMutex *mutex = &wMutex->RecursiveMutex;

  DWORD threadId = GetCurrentThreadId ();

  /**
   * If calling thread already owns the mutex, simply increment the lock count.
   */
  if (mutex->Owner == threadId) {
    if (unlikely (exclusiveLock)) {
      return EBUSY;
    }

    if (unlikely (mutex->LockCount == UINT_MAX)) {
      return EAGAIN;
    }

    mutex->LockCount++;
    return 0;
  }

  if (InterlockedCompareExchange (&mutex->LockState, Locked, Unlocked) != Unlocked) {
    return EBUSY;
  }

  mutex->Owner = threadId;
  mutex->LockCount = 1;

  return 0;
}

static int WinpthreadsRecursiveMutexUnlock (WinpthreadsMutex *wMutex) {
  WinpthreadsRecursiveMutex *mutex = &wMutex->RecursiveMutex;

  DWORD threadId = GetCurrentThreadId ();

  if (mutex->Owner != threadId) {
    return EPERM;
  }

  mutex->LockCount--;

  if (mutex->LockCount > 0) {
    return 0;
  }

  mutex->Owner = THREAD_ID_NO_OWNER;

  /**
   * If `mutex->LockState` is `LockedWithBlocking`, then some other thread is
   * waiting for `mutex->Event` to become signaled.
   */
  if (InterlockedExchange (&mutex->LockState, Unlocked) == LockedWithBlocking) {
    if (!SetEvent (mutex->Event)) {
      return EINVAL;
    }
  }

  return 0;
}

static const WinpthreadsMutexVtable WinpthreadsRecursiveMutexVtable = {
  .Init    = WinpthreadsRecursiveMutexInit,
  .Destroy = WinpthreadsRecursiveMutexDestroy,
  .Lock    = WinpthreadsRecursiveMutexLock,
  .TryLock = WinpthreadsRecursiveMutexTryLock,
  .Unlock  = WinpthreadsRecursiveMutexUnlock,
};

/*******************************************************************************
 * Implementation for public `pthread_mutexattr_*` functions.
 */

int pthread_mutexattr_init(pthread_mutexattr_t *a)
{
  *a = WINPTHREADS_MUTEX_ATTRIBUTES_DEFAULT.Value;
  return 0;
}

int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
{
  if (a == NULL) {
    return EINVAL;
  }

  memset (a, 0, sizeof (pthread_mutexattr_t));
  return 0;
}

int pthread_mutexattr_settype(pthread_mutexattr_t *a, int value)
{
  if (a == NULL) {
    return EINVAL;
  }

  WinpthreadsMutexAttributes *wMutexAttr = (WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  switch (value) {
    case PTHREAD_MUTEX_NORMAL:
    case PTHREAD_MUTEX_ERRORCHECK:
    case PTHREAD_MUTEX_RECURSIVE:
      wMutexAttr->Attributes.Type = value;
      return 0;
  }

  return EINVAL;
}

int pthread_mutexattr_gettype(const pthread_mutexattr_t *a, int *value)
{
  if (a == NULL || value == NULL) {
    return EINVAL;
  }

  const WinpthreadsMutexAttributes *wMutexAttr = (const WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  switch (wMutexAttr->Attributes.Type) {
    case PTHREAD_MUTEX_NORMAL:
    case PTHREAD_MUTEX_ERRORCHECK:
    case PTHREAD_MUTEX_RECURSIVE:
      *value = wMutexAttr->Attributes.Type;
      return 0;
  }

  return EINVAL;
}

int pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int value)
{
  if (a == NULL) {
    return EINVAL;
  }

  WinpthreadsMutexAttributes *wMutexAttr = (WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  switch (value) {
    case PTHREAD_PROCESS_PRIVATE:
    case PTHREAD_PROCESS_SHARED:
      wMutexAttr->Attributes.Shared = value;
      return 0;
  }

  return EINVAL;
}

int pthread_mutexattr_getpshared(const pthread_mutexattr_t *a, int *value)
{
  if (a == NULL || value == NULL) {
    return EINVAL;
  }

  const WinpthreadsMutexAttributes *wMutexAttr = (const WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  *value = !!wMutexAttr->Attributes.Shared;
  return 0;
}

int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int value)
{
  if (a == NULL) {
    return EINVAL;
  }

  WinpthreadsMutexAttributes *wMutexAttr = (WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  switch (value) {
    case PTHREAD_PRIO_NONE:
      wMutexAttr->Attributes.Protocol = value;
      return 0;
    /**
     * POSIX realtime extensions are not implemented.
     *
     * The pthread_mutexattr_setprotocol() function shall fail if:
     *
     * [ENOTSUP]
     *   The value specified by protocol is an unsupported value.
     */
    case PTHREAD_PRIO_INHERIT:
    case PTHREAD_PRIO_PROTECT:
      return ENOTSUP;
  }

  return EINVAL;
}

int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *a, int *value)
{
  if (a == NULL || value == NULL) {
    return EINVAL;
  }

  const WinpthreadsMutexAttributes *wMutexAttr = (const WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  switch (wMutexAttr->Attributes.Protocol) {
    case PTHREAD_PRIO_NONE:
    case PTHREAD_PRIO_INHERIT:
    case PTHREAD_PRIO_PROTECT:
      *value = wMutexAttr->Attributes.Protocol;
      return 0;
  }

  return EINVAL;
}

int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int value)
{
  if (a == NULL) {
    return EINVAL;
  }

  WinpthreadsMutexAttributes *wMutexAttr = (WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  if (value >= THREAD_PRIORITY_IDLE && value <= THREAD_PRIORITY_TIME_CRITICAL) {
    wMutexAttr->Attributes.PriorityCeiling = value;
    return 0;
  }

  return EINVAL;
}

int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *a, int *value)
{
  if (a == NULL || value == NULL) {
    return EINVAL;
  }

  const WinpthreadsMutexAttributes *wMutexAttr = (const WinpthreadsMutexAttributes *) a;

  if (wMutexAttr->Attributes.Magic != WINPTHREADS_MUTEX_ATTRIBUTES_MAGIC) {
    return EINVAL;
  }

  int priorityCeiling = wMutexAttr->Attributes.PriorityCeiling;

  if (priorityCeiling >= THREAD_PRIORITY_IDLE && priorityCeiling <= THREAD_PRIORITY_TIME_CRITICAL) {
    *value = priorityCeiling;
    return 0;
  }

  return EINVAL;
}

/*******************************************************************************
 * Implementation for public `pthread_mutex_*` functions.
 */

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

/**
 * Obtain pointer to `WinpthreadsMutex` structure pointed to by `m`.
 *
 * If `m` points to statically initialized `pthread_mutex_t` object,
 * allocate `WinpthreadsMutex` structure and store its address in `*m`.
 *
 * On success, stores pointer to `WinpthreadsMutex` structure in `*wMutex`.
 *
 * Returns zero on success and an error-code on failure.
 */
static WINPTHREADS_INLINE int WinpthreadsMutexGet(pthread_mutex_t *m, WinpthreadsMutex **wMutex)
{
  *wMutex = (WinpthreadsMutex *)*m;

  /**
   * We need to avoid race condition when more than one thread attempts to use
   * same statically initialized `pthread_mutex_t` object at the same time.
   *
   * Store newly initialized mutex in `wMutex`, which is a local variable
   * supplied by the caller, and only then store it in `m`.
   *
   * If some other thread was faster then us, destroy newly created mutex
   * and use mutex pointed to by `m`.
   */
  if (unlikely (STATIC_MUTEX_INITIALIZER (*wMutex))) {
    WinpthreadsMutexAttributes wMutexAttr = WINPTHREADS_MUTEX_ATTRIBUTES_DEFAULT;
    WinpthreadsMutex *volatile initializer = *wMutex;

    switch ((pthread_mutex_t)initializer) {
      case PTHREAD_NORMAL_MUTEX_INITIALIZER:
        wMutexAttr.Attributes.Type = PTHREAD_MUTEX_NORMAL;
        break;
      case PTHREAD_ERRORCHECK_MUTEX_INITIALIZER:
        wMutexAttr.Attributes.Type = PTHREAD_MUTEX_ERRORCHECK;
        break;
      case PTHREAD_RECURSIVE_MUTEX_INITIALIZER:
        wMutexAttr.Attributes.Type = PTHREAD_MUTEX_RECURSIVE;
        break;
      default:
        UNREACHABLE ();
    }

    int error_code = pthread_mutex_init ((pthread_mutex_t *)wMutex, &wMutexAttr.Value);

    if (error_code) {
      return error_code;
    }

    void *mutex = InterlockedCompareExchangePointer ((void **)m, *wMutex, initializer);

    /**
     * Some other thread was faster than us.
     */
    if (unlikely (mutex != initializer)) {
      pthread_mutex_destroy ((pthread_mutex_t *)wMutex);
      *wMutex = mutex;
    }
  }

  if (unlikely (*wMutex == NULL)) {
    return EINVAL;
  }

  return 0;
}

int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a)
{
  WinpthreadsMutexAttributes wMutexAttr = WINPTHREADS_MUTEX_ATTRIBUTES_DEFAULT;

  if (a != NULL) {
    int value;

    wMutexAttr.Value = *a;

    /**
     * POSIX:
     *
     * If an implementation detects that the value specified by the attr
     * argument to pthread_mutex_init() does not refer to an initialized mutex
     * attributes object, it is recommended that the function should fail and
     * report an [EINVAL] error.
     */
    if (pthread_mutexattr_gettype (&wMutexAttr.Value, &value) != 0) {
      return EINVAL;
    }

    if (pthread_mutexattr_getpshared (&wMutexAttr.Value, &value) != 0) {
      return EINVAL;
    }

    if (pthread_mutexattr_getprotocol (&wMutexAttr.Value, &value) != 0) {
      return EINVAL;
    }

    if (pthread_mutexattr_getprioceiling (&wMutexAttr.Value, &value) != 0) {
      return EINVAL;
    }

    if (wMutexAttr.Attributes.Shared) {
      return ENOSYS;
    }
  }

  const WinpthreadsMutexVtable *wMutexVtable = NULL;

  switch (wMutexAttr.Attributes.Type) {
    case PTHREAD_MUTEX_NORMAL:
      wMutexVtable = &WinpthreadsNormalMutexVtable;
      break;
    case PTHREAD_MUTEX_ERRORCHECK:
      wMutexVtable = &WinpthreadsErrorCheckMutexVtable;
      break;
    case PTHREAD_MUTEX_RECURSIVE:
      wMutexVtable = &WinpthreadsRecursiveMutexVtable;
      break;
    default:
      UNREACHABLE ();
  }

  WinpthreadsMutex *wMutex = NULL;

  int error_code = wMutexVtable->Init (&wMutex, &wMutexAttr);

  if (error_code) {
    return error_code;
  }

  wMutex->Base.Vtable = wMutexVtable;
  MemoryBarrier ();
  *m = (pthread_mutex_t)wMutex;

  return 0;
}

int pthread_mutex_destroy(pthread_mutex_t *m)
{
  /**
   * POSIX:
   *
   * If an implementation detects that the value specified by the mutex argument
   * to pthread_mutex_destroy() does not refer to an initialized mutex, it is
   * recommended that the function should fail and report an [EINVAL] error.
   */
  if (unlikely (m == NULL)) {
    return EINVAL;
  }

  WinpthreadsMutex *wMutex = (WinpthreadsMutex *)*m;

  if (unlikely (wMutex == NULL)) {
    return EINVAL;
  }

  /**
   * If `m` points to a static initializer, attempt to immediately invalidate
   * it in order to reduce window for other functions to attempt using it.
   */
  if (unlikely (STATIC_MUTEX_INITIALIZER (wMutex))) {
    WinpthreadsMutex *mutex = InterlockedCompareExchangePointer ((void **)m, NULL, wMutex);

    if (likely (mutex == wMutex) || unlikely (mutex == NULL)) {
      return 0;
    }

    wMutex = mutex;
  }

  int error_code = wMutex->Base.Vtable->TryLock (wMutex, TRUE);

  if (error_code) {
    return error_code;
  }

  InterlockedExchangePointer ((void **)m, NULL);
  wMutex->Base.Vtable->Destroy (wMutex);

  return 0;
}

int pthread_mutex_lock(pthread_mutex_t *m)
{
  WinpthreadsMutex *wMutex = NULL;

  int error_code = WinpthreadsMutexGet (m, &wMutex);

  if (error_code) {
    return error_code;
  }

  return wMutex->Base.Vtable->Lock (wMutex, NULL);
}

int pthread_mutex_trylock(pthread_mutex_t *m)
{
  WinpthreadsMutex *wMutex = NULL;

  int error_code = WinpthreadsMutexGet (m, &wMutex);

  if (error_code) {
    return error_code;
  }

  return wMutex->Base.Vtable->TryLock (wMutex, FALSE);
}

int pthread_mutex_timedlock64(pthread_mutex_t *m, const struct _timespec64 *ts)
{
  WinpthreadsMutex *wMutex = NULL;

  int error_code = WinpthreadsMutexGet (m, &wMutex);

  if (error_code) {
    return error_code;
  }

  /**
   * POSIX:
   *
   * Under no circumstance shall the function fail with a timeout if the mutex
   * can be locked immediately. The validity of the abstime parameter need
   * not be checked if the mutex can be locked immediately.
   */
  error_code = wMutex->Base.Vtable->TryLock (wMutex, FALSE);

  switch (error_code) {
    /**
     * Some thread owns the mutex.
     */
    case EBUSY:
      break;
    /**
     * Recursive lock count limit has been reached.
     */
    case EAGAIN:
    /**
     * The calling thread owns the mutex now.
     */
    case 0:
    /**
     * An unexpected error has occurred.
     */
    default:
      return error_code;
  }

  /**
   * The pthread_mutex_timedlock() function shall fail if:
   *
   * [EINVAL]
   *  The process or thread would have blocked, and the abstime parameter
   *  specified a nanoseconds field value less than zero or greater than
   *  or equal to 1000 million.
   */
  if (ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000) {
    return EINVAL;
  }

  return wMutex->Base.Vtable->Lock (wMutex, ts);
}

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)
{
  WinpthreadsMutex *wMutex = NULL;

  int error_code = WinpthreadsMutexGet (m, &wMutex);

  if (error_code) {
    return error_code;
  }

  return wMutex->Base.Vtable->Unlock (wMutex);
}
