diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-13 01:19:27 -0500 |
|---|---|---|
| committer | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-13 01:19:27 -0500 |
| commit | 1f9b827badb2de4c4eaae11c0d02242ec90af7f6 (patch) | |
| tree | 27acb295833e6eee730dd71f98db280d54c6a4ad /vendor/zgui/libs/winpthreads/src/mutex.c | |
| parent | b5d0c1dcd751f4735d9f6b45c805300000c9d171 (diff) | |
| download | particle-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.c | 381 |
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; -} |
