Blame src/functional/pthread_robust.c

Szabolcs Nagy 08cb39
#include <pthread.h>
Szabolcs Nagy 08cb39
#include <string.h>
Szabolcs Nagy 08cb39
#include <errno.h>
Szabolcs Nagy 08cb39
#include "test.h"
Szabolcs Nagy 08cb39
Szabolcs Nagy 08cb39
#define TEST(r, f, m) ( \
Szabolcs Nagy 4a6c16
	((r) = (f)) == 0 || (t_error("%s failed: (pshared==%d) %s (" m ")\n", #f, pshared, strerror(r)), 0) )
Szabolcs Nagy 08cb39
#define TESTX(r, f, x, m) ( \
Szabolcs Nagy 4a6c16
	((r) = (f)) == (x) || (t_error("%s failed: (pshared==%d) got %d \"%s\" want %d \"%s\" (" m ")\n", #f, pshared, r, strerror(r), x, strerror(x)), 0) )
Szabolcs Nagy 4a6c16
Szabolcs Nagy 4a6c16
static int pshared;
Szabolcs Nagy 08cb39
Szabolcs Nagy 08cb39
static void *start_lock(void *arg)
Szabolcs Nagy 08cb39
{
Szabolcs Nagy 08cb39
	pthread_mutex_lock(arg);
Szabolcs Nagy 08cb39
	return 0;
Szabolcs Nagy 08cb39
}
Szabolcs Nagy 08cb39
Szabolcs Nagy 08cb39
static void *start_wait(void *arg)
Szabolcs Nagy 08cb39
{
Szabolcs Nagy 08cb39
	void **args = arg;
Szabolcs Nagy 08cb39
	pthread_mutex_lock(args[1]);
Szabolcs Nagy 08cb39
	pthread_barrier_wait(args[0]);
Szabolcs Nagy 08cb39
	nanosleep(&(struct timespec){ .tv_nsec = 10000000 }, 0);
Szabolcs Nagy 08cb39
	return 0;
Szabolcs Nagy 08cb39
}
Szabolcs Nagy 08cb39
Szabolcs Nagy 4a6c16
void f(void)
Szabolcs Nagy 08cb39
{
Szabolcs Nagy 08cb39
	pthread_t td;
Szabolcs Nagy 08cb39
	int r;
Szabolcs Nagy 08cb39
	void *res;
Szabolcs Nagy 08cb39
	pthread_barrier_t barrier2;
Szabolcs Nagy 08cb39
	pthread_mutexattr_t mtx_a;
Szabolcs Nagy 08cb39
	pthread_mutex_t mtx;
Szabolcs Nagy 08cb39
Szabolcs Nagy 08cb39
	TEST(r, pthread_barrier_init(&barrier2, 0, 2), "creating barrier");
Szabolcs Nagy 08cb39
Szabolcs Nagy 08cb39
	/* Robust mutexes */
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutexattr_init(&mtx_a), "initializing mutex attr");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST), "setting robust attribute");
Szabolcs Nagy 4a6c16
	if (pshared)
Szabolcs Nagy 4a6c16
		TEST(r, pthread_mutexattr_setpshared(&mtx_a, PTHREAD_PROCESS_SHARED), "setting pshared attribute");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_init(&mtx, &mtx_a), "initializing robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_lock(&mtx), "locking robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_unlock(&mtx), "unlocking robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_create(&td, 0, start_lock, &mtx), "failed to create thread");
Szabolcs Nagy 08cb39
	TEST(r, pthread_join(td, &res), "joining thread");
Szabolcs Nagy 08cb39
	TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_unlock(&mtx), "unlocking orphaned robust mutex");
Szabolcs Nagy 08cb39
	TESTX(r, pthread_mutex_lock(&mtx), ENOTRECOVERABLE, "re-locking orphaned robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_destroy(&mtx), "destroying unrecoverable mutex");
Szabolcs Nagy 08cb39
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_init(&mtx, &mtx_a), "initializing robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_create(&td, 0, start_lock, &mtx), "failed to create thread");
Szabolcs Nagy 08cb39
	TEST(r, pthread_join(td, &res), "joining thread");
Szabolcs Nagy 08cb39
	TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_consistent(&mtx), "");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_unlock(&mtx), "unlocking orphaned robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_lock(&mtx), "re-locking orphaned robust mutex");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_destroy(&mtx), "destroying mutex");
Szabolcs Nagy 08cb39
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_init(&mtx, &mtx_a), "");
Szabolcs Nagy 08cb39
	TEST(r, pthread_create(&td, 0, start_wait, (void *[]){ &barrier2, &mtx }), "");
Szabolcs Nagy 08cb39
	r = pthread_barrier_wait(&barrier2);
Szabolcs Nagy 08cb39
	if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
Szabolcs Nagy cfa23c
		t_error("pthread_barrier_wait failed: got %d \"%s\", wanted either 0 or %d\n",
Szabolcs Nagy 08cb39
			r, strerror(r), PTHREAD_BARRIER_SERIAL_THREAD);
Szabolcs Nagy 4a6c16
	TEST(r, pthread_barrier_destroy(&barrier2), "");
Szabolcs Nagy 08cb39
	TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "");
Szabolcs Nagy 08cb39
	TEST(r, pthread_join(td, &res), "");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_consistent(&mtx), "");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_unlock(&mtx), "");
Szabolcs Nagy 08cb39
	TEST(r, pthread_mutex_destroy(&mtx), "");
Szabolcs Nagy 4a6c16
}
Szabolcs Nagy 08cb39
Szabolcs Nagy 4a6c16
int main(void)
Szabolcs Nagy 4a6c16
{
Szabolcs Nagy 4a6c16
	f();
Szabolcs Nagy 4a6c16
	pshared=1;
Szabolcs Nagy 4a6c16
	f();
Szabolcs Nagy cfa23c
	return t_status;
Szabolcs Nagy 08cb39
}