Example #1
0
void play(pthread_cond_t *cond, struct service *service, struct horse *horses, size_t horse_num) {
	init_race(service);

	while(run) {
		_pthread_mutex_lock(service->mfinished);
		if (service->finished) {
			_pthread_mutex_unlock(service->mfinished);

			// send if someone is waiting
			_pthread_cond_broadcast(cond);
check_for_horses:
			_pthread_mutex_lock(service->mcur_run);
			if (!service->cur_run) {
				_pthread_mutex_unlock(service->mcur_run);	
				break;
			}
			else {
				_pthread_mutex_unlock(service->mcur_run);
				_sleep(1, 0);
				goto check_for_horses;
			}
		}
		_pthread_mutex_unlock(service->mfinished);	
		_sleep(1, 0);
		_pthread_cond_broadcast(cond);
	}

	post_race(service, horses, horse_num);
} 
Example #2
0
int
_pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
{
	int wakeup = 0;

	if (once_control->state == ONCE_DONE)
		return (0);
	_pthread_mutex_lock(&once_lock);
	while (*(volatile int *)&(once_control->state) == ONCE_IN_PROGRESS)
		_pthread_cond_wait(&once_cv, &once_lock);
	/*
	 * If previous thread was canceled, then the state still
	 * could be ONCE_NEVER_DONE, we need to check it again.
	 */
	if (*(volatile int *)&(once_control->state) == ONCE_NEVER_DONE) {
		once_control->state = ONCE_IN_PROGRESS;
		_pthread_mutex_unlock(&once_lock);
		_pthread_cleanup_push(once_cancel_handler, once_control);
		init_routine();
		_pthread_cleanup_pop(0);
		_pthread_mutex_lock(&once_lock);
		once_control->state = ONCE_DONE;
		wakeup = 1;
	}
	_pthread_mutex_unlock(&once_lock);
	if (wakeup)
		_pthread_cond_broadcast(&once_cv);
	return (0);
}
Example #3
0
static void
once_cancel_handler(void *arg)
{
	pthread_once_t *once_control = arg;

	_pthread_mutex_lock(&once_lock);
	once_control->state = ONCE_NEVER_DONE;
	_pthread_mutex_unlock(&once_lock);
	_pthread_cond_broadcast(&once_cv);
}
Example #4
0
int
_pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
	pthread_rwlock_t prwlock;
	struct pthread *curthread;
	int ret;

	if (rwlock == NULL)
		return(EINVAL);

	prwlock = *rwlock;

	if (prwlock == NULL)
		return(EINVAL);

	/* grab the monitor lock */
	if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
		return(ret);

	curthread = _get_curthread();
	if (prwlock->state > 0) {
		curthread->rdlock_count--;
		prwlock->state--;
		if (prwlock->state == 0 && prwlock->blocked_writers)
			ret = _pthread_cond_signal(&prwlock->write_signal);
	} else if (prwlock->state < 0) {
		prwlock->state = 0;

		if (prwlock->blocked_writers)
			ret = _pthread_cond_signal(&prwlock->write_signal);
		else
			ret = _pthread_cond_broadcast(&prwlock->read_signal);
	} else
		ret = EINVAL;

	/* see the comment on this in pthread_rwlock_rdlock */
	_pthread_mutex_unlock(&prwlock->lock);

	return (ret);
}