int sem_wait (sem_t *sem) { long cur_v; int ret = 0; _sem_t *sv; HANDLE semh; struct sSemTimedWait arg; if (sem_std_enter (sem, &sv, 1) != 0) return -1; arg.ret = &ret; arg.p = sem; InterlockedDecrement (&sv->value); cur_v = sv->value; semh = sv->s; pthread_mutex_unlock (&sv->vlock); if (cur_v >= 0) return 0; else { pthread_cleanup_push (clean_wait_sem, (void *) &arg); ret = do_sema_b_wait_intern (semh, 2, INFINITE); pthread_cleanup_pop (ret); if (ret == EINVAL) return 0; } if (!ret) return 0; return sem_result (ret); }
static __attribute__((noinline)) int _mutex_trylock(pthread_mutex_t *m) { int r = 0; mutex_t *_m = (mutex_t *)*m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE && COND_OWNER(_m)) { InterlockedIncrement(&_m->count); return 0; } return EBUSY; } } else if (COND_LOCKED(_m)) return EBUSY; #if defined USE_MUTEX_Mutex r = do_sema_b_wait_intern (_m->h, 1, 0); if (r == ETIMEDOUT) r = EBUSY; #else /* USE_MUTEX_CriticalSection */ r = TryEnterCriticalSection(&_m->cs.cs) ? 0 : EBUSY; #endif if (!r) { _m->count = 1; SET_OWNER(_m); } return r; }
static WINPTHREADS_ATTRIBUTE((noinline)) int _mutex_trylock(pthread_mutex_t *m) { int r = 0; mutex_t *_m = (mutex_t *)*m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE && COND_OWNER(_m)) { InterlockedIncrement(&_m->count); return 0; } return EBUSY; } } else if (COND_LOCKED(_m)) return EBUSY; r = do_sema_b_wait_intern (_m->h, 1, 0); if (r == ETIMEDOUT) r = EBUSY; else if (!r) { _m->count = 1; SET_OWNER(_m); } return r; }
static int pthread_mutex_lock_intern(pthread_mutex_t *m, DWORD timeout) { mutex_t *_m; int r; r = mutex_ref(m); if(r) return r; _m = (mutex_t *)*m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (COND_OWNER(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE) { InterlockedIncrement(&_m->count); return mutex_unref(m,0); } return mutex_unref(m, EDEADLK); } } } else { #if !defined USE_MUTEX_Mutex if (COND_OWNER(_m)) { do { Sleep(0); /* waiter that owner gets released. */ } while (COND_OWNER(_m)); } #endif } #if defined USE_MUTEX_Mutex r = do_sema_b_wait_intern (_m->h, 1, timeout); #else /* USE_MUTEX_CriticalSection */ EnterCriticalSection(&_m->cs.cs); r = 0; #endif if (r == 0) { _m->count = 1; SET_OWNER(_m); } return mutex_unref(m,r); }
static int pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD timeout) { mutex_t *_m; int r; HANDLE h; r = mutex_ref (m); if (r) return r; _m = (mutex_t *) *m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (COND_OWNER(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE) { InterlockedIncrement(&_m->count); return mutex_unref(m,0); } return mutex_unref(m, EDEADLK); } } } h = _m->h; mutex_unref (m, 0); r = do_sema_b_wait_intern (h, 1, timeout); if (r != 0) return r; r = mutex_ref (m); if (r) return r; _m->count = 1; SET_OWNER(_m); return mutex_unref (m, r); }
int sem_timedwait (sem_t *sem, const struct timespec *t) { int cur_v, ret = 0; DWORD dwr; HANDLE semh; _sem_t *sv; struct sSemTimedWait arg; if (!t) return sem_wait (sem); dwr = dwMilliSecs(_pthread_rel_time_in_ms (t)); if (sem_std_enter (sem, &sv, 1) != 0) return -1; arg.ret = &ret; arg.p = sem; InterlockedDecrement (&sv->value); cur_v = sv->value; semh = sv->s; pthread_mutex_unlock(&sv->vlock); if (cur_v >= 0) return 0; else { pthread_cleanup_push (clean_wait_sem, (void *) &arg); ret = do_sema_b_wait_intern (semh, 2, dwr); pthread_cleanup_pop (ret); if (ret == EINVAL) return 0; } if (!ret) return 0; return sem_result (ret); }
static int pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD timeout) { mutex_t *_m; int r; HANDLE h; #if 0 int waited = 0; #endif r = mutex_ref (m); if (r) return r; _m = (mutex_t *) *m; if (_m->type != PTHREAD_MUTEX_NORMAL) { if (COND_LOCKED(_m)) { if (COND_OWNER(_m)) { if (_m->type == PTHREAD_MUTEX_RECURSIVE) { #if 0 printf("thread %d, recursive increment %p\n", GetCurrentThreadId(), m); #endif InterlockedIncrement(&_m->count); return mutex_unref(m,0); } #if 0 printf("thread %d, non recursive increment?!? %p\n", GetCurrentThreadId(), m); #endif return mutex_unref(m, EDEADLK); } } } h = _m->h; mutex_unref (m, 0); if(_m->owner) { #if 0 waited = 1; printf("thread %d, waiting for thread: %d on mutex %p for %d time\n", GetCurrentThreadId(), _m->owner, m, timeout); #endif } r = do_sema_b_wait_intern (h, 1, timeout); #if 0 if(waited) { printf("thread %d, resumed\n", GetCurrentThreadId()); } #endif if (r != 0) return r; r = mutex_ref (m); if (r) return r; _m->count = 1; SET_OWNER(_m); #if 0 printf("thread %d, setting owner of mutex %p\n", GetCurrentThreadId(), m); #endif return mutex_unref (m, r); }