aboutsummaryrefslogtreecommitdiff
path: root/vendor/zgui/libs/winpthreads/src/rwlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/zgui/libs/winpthreads/src/rwlock.c')
-rw-r--r--vendor/zgui/libs/winpthreads/src/rwlock.c537
1 files changed, 0 insertions, 537 deletions
diff --git a/vendor/zgui/libs/winpthreads/src/rwlock.c b/vendor/zgui/libs/winpthreads/src/rwlock.c
deleted file mode 100644
index 76669df..0000000
--- a/vendor/zgui/libs/winpthreads/src/rwlock.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- Copyright (c) 2011-2016 mingw-w64 project
-
- 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 "pthread.h"
-#include "thread.h"
-#include "ref.h"
-#include "rwlock.h"
-#include "misc.h"
-
-static pthread_spinlock_t rwl_global = PTHREAD_SPINLOCK_INITIALIZER;
-
-static WINPTHREADS_ATTRIBUTE((noinline)) int rwlock_static_init(pthread_rwlock_t *rw);
-
-static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_unref(volatile pthread_rwlock_t *rwl, int res)
-{
- pthread_spin_lock(&rwl_global);
-#ifdef WINPTHREAD_DBG
- assert((((rwlock_t *)*rwl)->valid == LIFE_RWLOCK) && (((rwlock_t *)*rwl)->busy > 0));
-#endif
- ((rwlock_t *)*rwl)->busy--;
- pthread_spin_unlock(&rwl_global);
- return res;
-}
-
-static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_ref(pthread_rwlock_t *rwl, int f )
-{
- int r = 0;
- if (STATIC_RWL_INITIALIZER(*rwl)) {
- r = rwlock_static_init(rwl);
- if (r != 0 && r != EBUSY)
- return r;
- }
- pthread_spin_lock(&rwl_global);
-
- if (!rwl || !*rwl || ((rwlock_t *)*rwl)->valid != LIFE_RWLOCK) r = EINVAL;
- else {
- ((rwlock_t *)*rwl)->busy ++;
- }
-
- pthread_spin_unlock(&rwl_global);
-
- return r;
-}
-
-static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_ref_unlock(pthread_rwlock_t *rwl )
-{
- int r = 0;
-
- pthread_spin_lock(&rwl_global);
-
- if (!rwl || !*rwl || ((rwlock_t *)*rwl)->valid != LIFE_RWLOCK) r = EINVAL;
- else if (STATIC_RWL_INITIALIZER(*rwl)) r= EPERM;
- else {
- ((rwlock_t *)*rwl)->busy ++;
- }
-
- pthread_spin_unlock(&rwl_global);
-
- return r;
-}
-
-static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_ref_destroy(pthread_rwlock_t *rwl, pthread_rwlock_t *rDestroy )
-{
- int r = 0;
-
- *rDestroy = (pthread_rwlock_t)NULL;
- pthread_spin_lock(&rwl_global);
-
- if (!rwl || !*rwl) r = EINVAL;
- else {
- rwlock_t *r_ = (rwlock_t *)*rwl;
- if (STATIC_RWL_INITIALIZER(*rwl)) *rwl = (pthread_rwlock_t)NULL;
- else if (r_->valid != LIFE_RWLOCK) r = EINVAL;
- else if (r_->busy) r = EBUSY;
- else {
- *rDestroy = *rwl;
- *rwl = (pthread_rwlock_t)NULL;
- }
- }
-
- pthread_spin_unlock(&rwl_global);
- return r;
-}
-
-static int rwlock_gain_both_locks(rwlock_t *rwlock)
-{
- int ret;
- ret = pthread_mutex_lock(&rwlock->mex);
- if (ret != 0)
- return ret;
- ret = pthread_mutex_lock(&rwlock->mcomplete);
- if (ret != 0)
- pthread_mutex_unlock(&rwlock->mex);
- return ret;
-}
-
-static int rwlock_free_both_locks(rwlock_t *rwlock, int last_fail)
-{
- int ret, ret2;
- ret = pthread_mutex_unlock(&rwlock->mcomplete);
- ret2 = pthread_mutex_unlock(&rwlock->mex);
- if (last_fail && ret2 != 0)
- ret = ret2;
- else if (!last_fail && !ret)
- ret = ret2;
- return ret;
-}
-
-#ifdef WINPTHREAD_DBG
-static int print_state = 0;
-void rwl_print_set(int state)
-{
- print_state = state;
-}
-
-void rwl_print(volatile pthread_rwlock_t *rwl, char *txt)
-{
- if (!print_state) return;
- rwlock_t *r = (rwlock_t *)*rwl;
- if (r == NULL) {
- printf("RWL%p %lu %s\n",(void *)*rwl,GetCurrentThreadId(),txt);
- } else {
- printf("RWL%p %lu V=%0X B=%d r=%ld w=%ld L=%p %s\n",
- (void *)*rwl,
- GetCurrentThreadId(),
- (int)r->valid,
- (int)r->busy,
- 0L,0L,NULL,txt);
- }
-}
-#endif
-
-static pthread_spinlock_t cond_locked = PTHREAD_SPINLOCK_INITIALIZER;
-
-static WINPTHREADS_ATTRIBUTE((noinline)) int rwlock_static_init(pthread_rwlock_t *rw)
-{
- int r;
- pthread_spin_lock(&cond_locked);
- if (*rw != PTHREAD_RWLOCK_INITIALIZER)
- {
- pthread_spin_unlock(&cond_locked);
- return EINVAL;
- }
- r = pthread_rwlock_init (rw, NULL);
- pthread_spin_unlock(&cond_locked);
-
- return r;
-}
-
-int pthread_rwlock_init (pthread_rwlock_t *rwlock_, const pthread_rwlockattr_t *attr)
-{
- rwlock_t *rwlock;
- int r;
-
- if(!rwlock_)
- return EINVAL;
- *rwlock_ = (pthread_rwlock_t)NULL;
- if ((rwlock = calloc(1, sizeof(*rwlock))) == NULL)
- return ENOMEM;
- rwlock->valid = DEAD_RWLOCK;
-
- rwlock->nex_count = rwlock->nsh_count = rwlock->ncomplete = 0;
- if ((r = pthread_mutex_init (&rwlock->mex, NULL)) != 0)
- {
- free(rwlock);
- return r;
- }
- if ((r = pthread_mutex_init (&rwlock->mcomplete, NULL)) != 0)
- {
- pthread_mutex_destroy(&rwlock->mex);
- free(rwlock);
- return r;
- }
- if ((r = pthread_cond_init (&rwlock->ccomplete, NULL)) != 0)
- {
- pthread_mutex_destroy(&rwlock->mex);
- pthread_mutex_destroy (&rwlock->mcomplete);
- free(rwlock);
- return r;
- }
- rwlock->valid = LIFE_RWLOCK;
- *rwlock_ = (pthread_rwlock_t)rwlock;
- return r;
-}
-
-int pthread_rwlock_destroy (pthread_rwlock_t *rwlock_)
-{
- rwlock_t *rwlock;
- pthread_rwlock_t rDestroy;
- int r, r2;
-
- pthread_spin_lock(&cond_locked);
- r = rwl_ref_destroy(rwlock_,&rDestroy);
- pthread_spin_unlock(&cond_locked);
-
- if(r) return r;
- if(!rDestroy) return 0; /* destroyed a (still) static initialized rwl */
-
- rwlock = (rwlock_t *)rDestroy;
- r = rwlock_gain_both_locks (rwlock);
- if (r != 0)
- {
- *rwlock_ = rDestroy;
- return r;
- }
- if (rwlock->nsh_count > rwlock->ncomplete || rwlock->nex_count > 0)
- {
- *rwlock_ = rDestroy;
- r = rwlock_free_both_locks(rwlock, 1);
- if (!r)
- r = EBUSY;
- return r;
- }
- rwlock->valid = DEAD_RWLOCK;
- r = rwlock_free_both_locks(rwlock, 0);
- if (r != 0) { *rwlock_ = rDestroy; return r; }
-
- r = pthread_cond_destroy(&rwlock->ccomplete);
- r2 = pthread_mutex_destroy(&rwlock->mex);
- if (!r) r = r2;
- r2 = pthread_mutex_destroy(&rwlock->mcomplete);
- if (!r) r = r2;
- rwlock->valid = DEAD_RWLOCK;
- free((void *)rDestroy);
- return 0;
-}
-
-int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock_)
-{
- rwlock_t *rwlock;
- int ret;
-
- /* pthread_testcancel(); */
-
- ret = rwl_ref(rwlock_,0);
- if(ret != 0) return ret;
-
- rwlock = (rwlock_t *)*rwlock_;
-
- ret = pthread_mutex_lock(&rwlock->mex);
- if (ret != 0) return rwl_unref(rwlock_, ret);
- InterlockedIncrement((long*)&rwlock->nsh_count);
- if (rwlock->nsh_count == INT_MAX)
- {
- ret = pthread_mutex_lock(&rwlock->mcomplete);
- if (ret != 0)
- {
- pthread_mutex_unlock(&rwlock->mex);
- return rwl_unref(rwlock_,ret);
- }
- rwlock->nsh_count -= rwlock->ncomplete;
- rwlock->ncomplete = 0;
- ret = rwlock_free_both_locks(rwlock, 0);
- return rwl_unref(rwlock_, ret);
- }
- ret = pthread_mutex_unlock(&rwlock->mex);
- return rwl_unref(rwlock_, ret);
-}
-
-int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct timespec *ts)
-{
- rwlock_t *rwlock;
- int ret;
-
- /* pthread_testcancel(); */
-
- ret = rwl_ref(rwlock_,0);
- if(ret != 0) return ret;
-
- rwlock = (rwlock_t *)*rwlock_;
- if ((ret = pthread_mutex_timedlock (&rwlock->mex, ts)) != 0)
- return rwl_unref(rwlock_, ret);
- InterlockedIncrement(&rwlock->nsh_count);
- if (rwlock->nsh_count == INT_MAX)
- {
- ret = pthread_mutex_timedlock(&rwlock->mcomplete, ts);
- if (ret != 0)
- {
- if (ret == ETIMEDOUT)
- InterlockedIncrement(&rwlock->ncomplete);
- pthread_mutex_unlock(&rwlock->mex);
- return rwl_unref(rwlock_, ret);
- }
- rwlock->nsh_count -= rwlock->ncomplete;
- rwlock->ncomplete = 0;
- ret = rwlock_free_both_locks(rwlock, 0);
- return rwl_unref(rwlock_, ret);
- }
- ret = pthread_mutex_unlock(&rwlock->mex);
- return rwl_unref(rwlock_, ret);
-}
-
-int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock_)
-{
- rwlock_t *rwlock;
- int ret;
-
- ret = rwl_ref(rwlock_,RWL_TRY);
- if(ret != 0) return ret;
-
- rwlock = (rwlock_t *)*rwlock_;
- ret = pthread_mutex_trylock(&rwlock->mex);
- if (ret != 0)
- return rwl_unref(rwlock_, ret);
- InterlockedIncrement(&rwlock->nsh_count);
- if (rwlock->nsh_count == INT_MAX)
- {
- ret = pthread_mutex_lock(&rwlock->mcomplete);
- if (ret != 0)
- {
- pthread_mutex_unlock(&rwlock->mex);
- return rwl_unref(rwlock_, ret);
- }
- rwlock->nsh_count -= rwlock->ncomplete;
- rwlock->ncomplete = 0;
- ret = rwlock_free_both_locks(rwlock, 0);
- return rwl_unref(rwlock_, ret);
- }
- ret = pthread_mutex_unlock(&rwlock->mex);
- return rwl_unref(rwlock_,ret);
-}
-
-int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock_)
-{
- rwlock_t *rwlock;
- int ret;
-
- ret = rwl_ref(rwlock_,RWL_TRY);
- if(ret != 0) return ret;
-
- rwlock = (rwlock_t *)*rwlock_;
- ret = pthread_mutex_trylock (&rwlock->mex);
- if (ret != 0)
- return rwl_unref(rwlock_, ret);
- ret = pthread_mutex_trylock(&rwlock->mcomplete);
- if (ret != 0)
- {
- int r1 = pthread_mutex_unlock(&rwlock->mex);
- if (r1 != 0)
- ret = r1;
- return rwl_unref(rwlock_, ret);
- }
- if (rwlock->nex_count != 0)
- return rwl_unref(rwlock_, EBUSY);
- if (rwlock->ncomplete > 0)
- {
- rwlock->nsh_count -= rwlock->ncomplete;
- rwlock->ncomplete = 0;
- }
- if (rwlock->nsh_count > 0)
- {
- ret = rwlock_free_both_locks(rwlock, 0);
- if (!ret)
- ret = EBUSY;
- return rwl_unref(rwlock_, ret);
- }
- rwlock->nex_count = 1;
- return rwl_unref(rwlock_, 0);
-}
-
-int pthread_rwlock_unlock (pthread_rwlock_t *rwlock_)
-{
- rwlock_t *rwlock;
- int ret;
-
- ret = rwl_ref_unlock(rwlock_);
- if(ret != 0) return ret;
-
- rwlock = (rwlock_t *)*rwlock_;
- if (rwlock->nex_count == 0)
- {
- ret = pthread_mutex_lock(&rwlock->mcomplete);
- if (!ret)
- {
- int r1;
- InterlockedIncrement(&rwlock->ncomplete);
- if (rwlock->ncomplete == 0)
- ret = pthread_cond_signal(&rwlock->ccomplete);
- r1 = pthread_mutex_unlock(&rwlock->mcomplete);
- if (!ret)
- ret = r1;
- }
- }
- else
- {
- InterlockedDecrement(&rwlock->nex_count);
- ret = rwlock_free_both_locks(rwlock, 0);
- }
- return rwl_unref(rwlock_, ret);
-}
-
-static void st_cancelwrite (void *arg)
-{
- rwlock_t *rwlock = (rwlock_t *)arg;
-
- rwlock->nsh_count = - rwlock->ncomplete;
- rwlock->ncomplete = 0;
- rwlock_free_both_locks(rwlock, 0);
-}
-
-int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock_)
-{
- rwlock_t *rwlock;
- int ret;
-
- /* pthread_testcancel(); */
- ret = rwl_ref(rwlock_,0);
- if(ret != 0) return ret;
-
- rwlock = (rwlock_t *)*rwlock_;
- ret = rwlock_gain_both_locks(rwlock);
- if (ret != 0)
- return rwl_unref(rwlock_,ret);
-
- if (rwlock->nex_count == 0)
- {
- if (rwlock->ncomplete > 0)
- {
- rwlock->nsh_count -= rwlock->ncomplete;
- rwlock->ncomplete = 0;
- }
- if (rwlock->nsh_count > 0)
- {
- rwlock->ncomplete = -rwlock->nsh_count;
- pthread_cleanup_push(st_cancelwrite, (void *) rwlock);
- do {
- ret = pthread_cond_wait(&rwlock->ccomplete, &rwlock->mcomplete);
- } while (!ret && rwlock->ncomplete < 0);
-
- pthread_cleanup_pop(!ret ? 0 : 1);
- if (!ret)
- rwlock->nsh_count = 0;
- }
- }
- if(!ret)
- InterlockedIncrement((long*)&rwlock->nex_count);
- return rwl_unref(rwlock_,ret);
-}
-
-int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct timespec *ts)
-{
- int ret;
- rwlock_t *rwlock;
-
- /* pthread_testcancel(); */
- if (!rwlock_ || !ts)
- return EINVAL;
- if ((ret = rwl_ref(rwlock_,0)) != 0)
- return ret;
- rwlock = (rwlock_t *)*rwlock_;
-
- ret = pthread_mutex_timedlock(&rwlock->mex, ts);
- if (ret != 0)
- return rwl_unref(rwlock_,ret);
- ret = pthread_mutex_timedlock (&rwlock->mcomplete, ts);
- if (ret != 0)
- {
- pthread_mutex_unlock(&rwlock->mex);
- return rwl_unref(rwlock_,ret);
- }
- if (rwlock->nex_count == 0)
- {
- if (rwlock->ncomplete > 0)
- {
- rwlock->nsh_count -= rwlock->ncomplete;
- rwlock->ncomplete = 0;
- }
- if (rwlock->nsh_count > 0)
- {
- rwlock->ncomplete = -rwlock->nsh_count;
- pthread_cleanup_push(st_cancelwrite, (void *) rwlock);
- do {
- ret = pthread_cond_timedwait(&rwlock->ccomplete, &rwlock->mcomplete, ts);
- } while (rwlock->ncomplete < 0 && !ret);
- pthread_cleanup_pop(!ret ? 0 : 1);
-
- if (!ret)
- rwlock->nsh_count = 0;
- }
- }
- if(!ret)
- InterlockedIncrement((long*)&rwlock->nex_count);
- return rwl_unref(rwlock_,ret);
-}
-
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
-{
- if (!a)
- return EINVAL;
- return 0;
-}
-
-int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
-{
- if (!a)
- return EINVAL;
- *a = PTHREAD_PROCESS_PRIVATE;
- return 0;
-}
-
-int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s)
-{
- if (!a || !s)
- return EINVAL;
- *s = *a;
- return 0;
-}
-
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s)
-{
- if (!a || (s != PTHREAD_PROCESS_SHARED && s != PTHREAD_PROCESS_PRIVATE))
- return EINVAL;
- *a = s;
- return 0;
-}