aboutsummaryrefslogtreecommitdiff
path: root/vendor/zgui/libs/winpthreads/src/mutex.c
diff options
context:
space:
mode:
authorNic Gaffney <gaffney_nic@protonmail.com>2025-10-13 01:19:27 -0500
committerNic Gaffney <gaffney_nic@protonmail.com>2025-10-13 01:19:27 -0500
commit1f9b827badb2de4c4eaae11c0d02242ec90af7f6 (patch)
tree27acb295833e6eee730dd71f98db280d54c6a4ad /vendor/zgui/libs/winpthreads/src/mutex.c
parentb5d0c1dcd751f4735d9f6b45c805300000c9d171 (diff)
downloadparticle-sim-1f9b827badb2de4c4eaae11c0d02242ec90af7f6.tar.gz
Updating to zig 0.15.1
Diffstat (limited to 'vendor/zgui/libs/winpthreads/src/mutex.c')
-rw-r--r--vendor/zgui/libs/winpthreads/src/mutex.c381
1 files changed, 0 insertions, 381 deletions
diff --git a/vendor/zgui/libs/winpthreads/src/mutex.c b/vendor/zgui/libs/winpthreads/src/mutex.c
deleted file mode 100644
index 866e18d..0000000
--- a/vendor/zgui/libs/winpthreads/src/mutex.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- 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.
-*/
-
-#include <windows.h>
-#include <stdio.h>
-#include <malloc.h>
-#include <stdbool.h>
-#include "pthread.h"
-#include "misc.h"
-
-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;
-
-/* Whether a mutex is still a static initializer (not a pointer to
- a mutex_impl_t). */
-static bool
-is_static_initializer(pthread_mutex_t m)
-{
- /* Treat 0 as a static initializer as well (for normal mutexes),
- to tolerate sloppy code in libgomp. (We should rather fix that code!) */
- intptr_t v = (intptr_t)m;
- return v >= -3 && v <= 0;
-/* Should be simple:
- return (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 inline mutex_impl_t *
-mutex_impl(pthread_mutex_t *m)
-{
- mutex_impl_t *mi = (mutex_impl_t *)*m;
- if (is_static_initializer((pthread_mutex_t)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 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_timedlock(pthread_mutex_t *m, const struct timespec *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_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 EINVAL;
- 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 (!is_static_initializer((pthread_mutex_t)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 || (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 || (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;
-}