コード例 #1
0
ファイル: __wait.c プロジェクト: 4ian/emscripten
void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
{
	int spins=10000;
	if (priv) priv = 128; priv=0;
	while (spins--) {
		if (*addr==val) a_spin();
		else return;
	}
	if (waiters) a_inc(waiters);
	while (*addr==val) {
#ifdef __EMSCRIPTEN__
		if (pthread_self()->cancelasync == PTHREAD_CANCEL_ASYNCHRONOUS) {
			// Must wait in slices in case this thread is cancelled in between.
			int e;
			do {
				if (_pthread_isduecanceled(pthread_self())) {
					if (waiters) a_dec(waiters);
					return;
				}
				e = emscripten_futex_wait((void*)addr, val, 100);
			} while(e == -ETIMEDOUT);
		} else {
			// Can wait in one go.
			emscripten_futex_wait((void*)addr, val, INFINITY);
		}
#else
		__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0);
#endif
	}
	if (waiters) a_dec(waiters);
}
コード例 #2
0
int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *at)
{
	int r, w=0;
	while ((r=pthread_mutex_trylock(m)) == EBUSY) {
		if (!(r=m->_m_lock) || (r&0x40000000)) continue;
		if (!w) a_inc(&m->_m_waiters), w++;
		if (__timedwait(&m->_m_lock, r, CLOCK_REALTIME, at, 0) == ETIMEDOUT) {
			if (w) a_dec(&m->_m_waiters);
			return ETIMEDOUT;
		}
	}
	if (w) a_dec(&m->_m_waiters);
	return r;
}
コード例 #3
0
ファイル: task.c プロジェクト: onnlucky/hotel
static tlHandle tlTaskDone(tlTask* task) {
    trace("%p done: %s%s", task, tl_str(task->value), tlTaskHasError(task)? " (error)":"");
    assert(!task->stack);
    assert(task->value);
    assert(task->state == TL_STATE_RUN);
    task->state = tlTaskHasError(task)? TL_STATE_ERROR : TL_STATE_DONE;
    tlVm* vm = tlTaskGetVm(task);
    a_dec(&vm->tasks);
    a_dec(&vm->runnable);
    task->worker = vm->waiter;
    signalWaiters(task);
    signalVm(task);
    if (tlBlockingTaskIs(task)) tlBlockingTaskDone(task);
    if (task->debugger) tlDebuggerTaskDone(task->debugger, task);
    if (task->yields) tlQueueClose(task->yields);
    return tlTaskNotRunning;
}
コード例 #4
0
ファイル: __wait.c プロジェクト: chneukirchen/musl-chris2
void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
{
	int spins=50000;
	if (priv) priv = 128; priv=0;
	while (spins--) {
		if (*addr==val) a_spin();
		else return;
	}
	if (waiters) a_inc(waiters);
	while (*addr==val)
		__syscall(SYS_futex, (long)addr, FUTEX_WAIT|priv, val, 0);
	if (waiters) a_dec(waiters);
}
コード例 #5
0
static void unwait(pthread_cond_t *c, pthread_mutex_t *m)
{
    /* Removing a waiter is non-trivial if we could be using requeue
     * based broadcast signals, due to mutex access issues, etc. */

    if (c->_c_mutex == (void *)-1) {
        a_dec(&c->_c_waiters);
        if (c->_c_destroy) __wake(&c->_c_waiters, 1, 0);
        return;
    }

    while (a_swap(&c->_c_lock, 1))
        __wait(&c->_c_lock, &c->_c_lockwait, 1, 1);

    if (c->_c_waiters2) c->_c_waiters2--;
    else a_dec(&m->_m_waiters);

    a_store(&c->_c_lock, 0);
    if (c->_c_lockwait) __wake(&c->_c_lock, 1, 1);

    a_dec(&c->_c_waiters);
    if (c->_c_destroy) __wake(&c->_c_waiters, 1, 1);
}
コード例 #6
0
ファイル: sem_timedwait.c プロジェクト: KGG814/AOS
int sem_timedwait(sem_t *sem, const struct timespec *at)
{
	while (sem_trywait(sem)) {
		int r;
		a_inc(sem->__val+1);
		a_cas(sem->__val, 0, -1);
		r = __timedwait(sem->__val, -1, CLOCK_REALTIME, at, cleanup, sem->__val+1, 0);
		a_dec(sem->__val+1);
		if (r) {
			errno = r;
			return -1;
		}
	}
	return 0;
}
コード例 #7
0
ファイル: task.c プロジェクト: onnlucky/hotel
tlArray* tlTaskWaitFor(tlTask* task, tlHandle on) {
    assert(tlTaskIs(task));
    assert(task->state == TL_STATE_RUN);
    assert(task->value);
    trace("%s.value: %s", tl_str(task), tl_str(task->value));
    tlVm* vm = tlTaskGetVm(task);
    task->state = TL_STATE_WAIT;
    task->waitFor = on;

    if (checkDeadlock(task, on)) {
        task->state = TL_STATE_RUN;
        return deadlocked(task, on);
    }

    if (!tlWorkerIsBound(task->worker)) task->worker = vm->waiter;
    a_dec(&vm->runnable);
    return null;
}
コード例 #8
0
ファイル: pthread_mutex_timedlock.c プロジェクト: KGG814/AOS
int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *at)
{
	int r, t;

	if (m->_m_type == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY))
		return 0;

	while ((r=pthread_mutex_trylock(m)) == EBUSY) {
		if (!(r=m->_m_lock) || (r&0x40000000)) continue;
		if ((m->_m_type&3) == PTHREAD_MUTEX_ERRORCHECK
		 && (r&0x1fffffff) == pthread_self()->tid)
			return EDEADLK;

		a_inc(&m->_m_waiters);
		t = r | 0x80000000;
		a_cas(&m->_m_lock, r, t);
		r = __timedwait(&m->_m_lock, t, CLOCK_REALTIME, at, 0, 0, 0);
		a_dec(&m->_m_waiters);
		if (r && r != EINTR) break;
	}
	return r;
}
コード例 #9
0
ファイル: task.c プロジェクト: onnlucky/hotel
void tlTaskReadyExternal(tlTask* task) {
    tlVm* vm = tlTaskGetVm(task);
    if (!task->background) a_dec(&vm->waitevent);
    tlTaskReady(task);
    if (vm->signalcb) vm->signalcb();
}
コード例 #10
0
ファイル: task.c プロジェクト: onnlucky/hotel
void tlTaskWaitNothing2(tlTask* task) {
    tlVm* vm = tlTaskGetVm(task);
    a_dec(&vm->runnable);
}
コード例 #11
0
ファイル: sem_timedwait.c プロジェクト: 4ian/emscripten
static void cleanup(void *p)
{
	a_dec(p);
}
コード例 #12
0
ファイル: worker.c プロジェクト: onnlucky/hotel
void tlVmDecExternal(tlVm* vm) {
    assert(vm);
    a_dec(&vm->waitevent);
    if (vm->signalcb) vm->signalcb();
}