示例#1
0
void *
mvar_try_take (MVar *const mvar)
{
	int e = 0;
	void *value = NULL;
	assert (mvar);

	e = mvar_lock (mvar);
	KNOWN_ERRORS_1 (e, EDEADLK);
	RECOVERABLE_1 (e, e_lock, EDEADLK);

	/* Don't block, just test. */
	if (mvar->value) {

		/* Exchange value for NULL. */
		value = mvar->value;
		mvar->value = NULL;

		/* Notify someone waiting to put. */
		e = pthread_cond_signal (&mvar->put);
		KNOWN_ERRORS_1 (e, EINVAL);
		UNRECOVERABLE (e);

	}

	mvar_unlock (mvar);
e_lock:

	/* Return old value. */
	return value;
}
示例#2
0
/* Returns NULL and sets errno to EDEADLK if a deadlock would occur. */
void *
mvar_read (MVar *const mvar)
{
	int e = 0;
	void *value;
	assert (mvar);

	e = mvar_lock (mvar);
	KNOWN_ERRORS_1 (e, EDEADLK);
	RECOVERABLE_1 (e, e_lock, EDEADLK);

	/* Block until non-empty. Loop to handle spurious wakeups. */
	while (!mvar->value) {
		e = pthread_cond_wait (&mvar->read, &mvar->lock);
		KNOWN_ERRORS_1 (e, EINVAL);
		UNRECOVERABLE (e);
	}

	/* Perform actual load. */
	value = mvar->value;

	mvar_unlock (mvar);

	/* Return new value. */
	return value;

e_lock:
	errno = e;
	return NULL;

}
示例#3
0
void
mvar_unlock (MVar *mvar)
{
	int e = 0;
	assert (mvar);
	e = pthread_mutex_unlock (&mvar->lock);
	KNOWN_ERRORS_2 (e, EINVAL, EPERM);
	UNRECOVERABLE (e);
}
示例#4
0
int
mvar_init (MVar *const mvar, void *const value)
{
	int e = 0;
	assert (mvar);

	e = pthread_mutex_init (&mvar->lock, NULL);
	MUTEX_INIT (e, e_lock);

	e = pthread_cond_init (&mvar->put, NULL);
	COND_INIT (e, e_put);

	e = pthread_cond_init (&mvar->read, NULL);
	COND_INIT (e, e_read);

	e = pthread_cond_init (&mvar->take, NULL);
	COND_INIT (e, e_take);

	mvar->value = NULL;

	if (value)
		e = mvar_put (mvar, value);

	goto end;

	e = pthread_cond_destroy (&mvar->take);
	UNRECOVERABLE (e);
e_take:

	e = pthread_cond_destroy (&mvar->read);
	UNRECOVERABLE (e);
e_read:

	e = pthread_cond_destroy (&mvar->put);
	UNRECOVERABLE (e);
e_put:

	e = pthread_mutex_destroy (&mvar->lock);
	UNRECOVERABLE (e);
e_lock:

end:
	return e;
}
示例#5
0
int
mvar_put (MVar *const mvar, void *const value)
{
	int e = 0;
	assert (mvar);

	/* Putting nothing in does nothing. */
	if (!value) {
		e = EINVAL;
		RECOVERABLE_1 (e, e_arg, EINVAL);
	}

	e = mvar_lock (mvar);
	KNOWN_ERRORS_1 (e, EINVAL);
	RECOVERABLE_1 (e, e_lock, EDEADLK);
	UNRECOVERABLE (e);

	/* Block until empty. Loop to handle spurious wakeups. */
	while (mvar->value) {
		e = pthread_cond_wait (&mvar->put, &mvar->lock);
		KNOWN_ERRORS_1 (e, EINVAL);
		UNRECOVERABLE (e);
	}

	/* Perform the actual store. */
	mvar->value = value;

	/* Notify everyone waiting to read. */
	e = pthread_cond_broadcast (&mvar->read);
	KNOWN_ERRORS_1 (e, EINVAL);
	UNRECOVERABLE (e);

	/* Notify someone waiting to take. Assumes fairness! */
	e = pthread_cond_signal (&mvar->take);
	KNOWN_ERRORS_1 (e, EINVAL);
	UNRECOVERABLE (e);

	mvar_unlock (mvar);

e_lock:
e_arg:

	return e;
}
示例#6
0
int
mvar_try_put (MVar *const mvar, void *const value)
{
	int e = 0;
	assert (mvar);

	/* Putting nothing in does nothing. */
	if (!value) {
		e = EINVAL;
		RECOVERABLE_1 (e, e_arg, EINVAL);
	}

	e = mvar_lock (mvar);
	KNOWN_ERRORS_1 (e, EDEADLK);
	RECOVERABLE_1 (e, e_lock, EDEADLK);

	/* Don't block, just test. */
	if (!mvar->value) {

		mvar->value = value;

		/* Notify everyone waiting to read. */
		e = pthread_cond_broadcast (&mvar->read);
		KNOWN_ERRORS_1 (e, EINVAL);
		UNRECOVERABLE (e);

		/* Notify someone waiting to take. Assumes fairness! */
		e = pthread_cond_signal (&mvar->take);
		KNOWN_ERRORS_1 (e, EINVAL);
		UNRECOVERABLE (e);

	}

	mvar_unlock (mvar);
e_lock:
e_arg:

	return e;

}
示例#7
0
void *
mvar_take (MVar *const mvar)
{
	int e = 0;
	void *value;
	assert (mvar);

	mvar_lock (mvar);
	KNOWN_ERRORS_1 (e, EDEADLK);
	RECOVERABLE_1 (e, e_lock, EDEADLK);

	/* Block until non-empty. Loop to handle spurious wakeups. */
	while (!mvar->value) {
		e = pthread_cond_wait (&mvar->take, &mvar->lock);
		KNOWN_ERRORS_1 (e, EINVAL);
		UNRECOVERABLE (e);
	}

	/* Exchange value for NULL. */
	value = mvar->value;
	mvar->value = NULL;

	/* Notify someone waiting to put. */
	e = pthread_cond_signal (&mvar->put);
	KNOWN_ERRORS_1 (e, EINVAL);
	UNRECOVERABLE (e);

	mvar_unlock (mvar);

	/* Return old value. */
	return value;

e_lock:
	errno = e;
	return NULL;

}
示例#8
0
int
mvar_lock (MVar *mvar)
{
	int e = 0;
	assert (mvar);

	e = pthread_mutex_lock (&mvar->lock);
	KNOWN_ERRORS_2 (e, EDEADLK, EINVAL);
	RECOVERABLE_1 (e, e_lock, EDEADLK);
	UNRECOVERABLE (e);

	return 0;

e_lock:
	return e;
}
示例#9
0
 TM_INLINE
 static void write(const double*, double, TxThread*)
 {
     UNRECOVERABLE("You should not be writing a const double!");
 }
示例#10
0
 TM_INLINE
 static void write(const float*, float, TxThread*)
 {
     UNRECOVERABLE("You should not be writing a const float!");
 }