/* Copyright (c) 2016 Google, Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details. */

#include <utest/utest.h>
#include <parlib/uthread.h>
#include <pthread.h>
#include <time.h>

TEST_SUITE("CV");

/* <--- Begin definition of test cases ---> */

struct common_args {
	uth_cond_var_t			*cv;
	uth_mutex_t			*mtx;
	bool				flag;
	unsigned int			wait_sleep;
	unsigned int			sig_sleep;
};

#define PTH_TEST_TRUE			(void*)1

bool test_signal_no_wait(void)
{
	uth_cond_var_t *cv = uth_cond_var_alloc();

	uth_cond_var_broadcast(cv);
	uth_cond_var_signal(cv);
	pthread_yield();
	uth_cond_var_free(cv);
	return TRUE;
}

void *__cv_signaller(void *arg)
{
	struct common_args *args = (struct common_args*)arg;

	uthread_usleep(args->sig_sleep);
	uth_mutex_lock(args->mtx);
	args->flag = TRUE;
	uth_mutex_unlock(args->mtx);
	/* We can actually signal outside the mutex if we want.  Remember the
	 * invariant: whenever the flag is set from FALSE to TRUE, all waiters
	 * that saw FALSE are on the CV's waitqueue.  That's true even after we
	 * unlock the mutex. */
	uth_cond_var_signal(args->cv);
	return PTH_TEST_TRUE;
}

void *__cv_broadcaster(void *arg)
{
	struct common_args *args = (struct common_args*)arg;

	uthread_usleep(args->sig_sleep);
	uth_mutex_lock(args->mtx);
	args->flag = TRUE;
	uth_mutex_unlock(args->mtx);
	/* We can actually signal outside the mutex if we want.  Remember the
	 * invariant: whenever the flag is set from FALSE to TRUE, all waiters
	 * that saw FALSE are on the CV's waitqueue.  That's true even after we
	 * unlock the mutex. */
	uth_cond_var_broadcast(args->cv);
	return PTH_TEST_TRUE;
}

void *__cv_waiter(void *arg)
{
	struct common_args *args = (struct common_args*)arg;

	uthread_usleep(args->wait_sleep);
	uth_mutex_lock(args->mtx);
	while (!args->flag)
		uth_cond_var_wait(args->cv, args->mtx);
	UT_ASSERT(args->flag);
	uth_mutex_unlock(args->mtx);
	return PTH_TEST_TRUE;
}

/* Basic one signaller, one receiver.  We want to vary the amount of time the
 * sender and receiver delays, starting with (1ms, 0ms) and ending with (0ms,
 * 1ms).  At each extreme, such as with the sender waiting 1ms, the
 * receiver/waiter should hit the "check and wait" point well before the
 * sender/signaller hits the "change state and signal" point. */
bool test_signal(void)
{
	struct common_args local_a, *args = &local_a;
	pthread_t signaller, waiter;
	void *sig_join, *wait_join;
	int ret;
	static uth_mutex_t static_mtx = UTH_MUTEX_INIT;
	static uth_cond_var_t static_cv = UTH_COND_VAR_INIT;

	/* Also testing the static initializers.  Note we never free these. */
	args->cv = &static_cv;
	args->mtx = &static_mtx;

	for (int i = 0; i < 1000; i += 10) {
		args->flag = FALSE;
		args->wait_sleep = i;
		args->sig_sleep = 1000 - i;

		ret = pthread_create(&waiter, 0, __cv_waiter, args);
		UT_ASSERT(!ret);
		ret = pthread_create(&signaller, 0, __cv_signaller, args);
		UT_ASSERT(!ret);
		ret = pthread_join(waiter, &wait_join);
		UT_ASSERT(!ret);
		ret = pthread_join(signaller, &sig_join);
		UT_ASSERT(!ret);
		UT_ASSERT_M("Waiter Failed", wait_join == PTH_TEST_TRUE);
		UT_ASSERT_M("Signaller Failed", sig_join == PTH_TEST_TRUE);
	}

	return TRUE;
}

bool test_broadcast(void)
{
	#define NR_WAITERS 20
	struct common_args local_a, *args = &local_a;
	pthread_t bcaster, waiters[NR_WAITERS];
	void *bcast_join, *wait_joins[NR_WAITERS];
	int ret;

	args->cv = uth_cond_var_alloc();
	args->mtx = uth_mutex_alloc();
	args->flag = FALSE;
	args->wait_sleep = 0;
	args->sig_sleep = 1000;

	for (int i = 0; i < NR_WAITERS; i++) {
		ret = pthread_create(&waiters[i], 0, __cv_waiter, args);
		UT_ASSERT(!ret);
	}
	ret = pthread_create(&bcaster, 0, __cv_broadcaster, args);
	UT_ASSERT(!ret);

	ret = pthread_join(bcaster, &bcast_join);
	UT_ASSERT(!ret);
	UT_ASSERT_M("Broadcaster Failed", bcast_join == PTH_TEST_TRUE);
	for (int i = 0; i < NR_WAITERS; i++) {
		ret = pthread_join(waiters[i], &wait_joins[i]);
		UT_ASSERT(!ret);
		UT_ASSERT_M("Waiter Failed", wait_joins[i] == PTH_TEST_TRUE);
	}

	uth_cond_var_free(args->cv);
	uth_mutex_free(args->mtx);
	return TRUE;
}

static void *__cv_signaller_no_mutex(void *arg)
{
	struct common_args *args = (struct common_args*)arg;

	uthread_usleep(args->sig_sleep);
	uth_cond_var_lock(args->cv);
	args->flag = TRUE;
	__uth_cond_var_signal_and_unlock(args->cv);
	return PTH_TEST_TRUE;
}

static void *__cv_broadcaster_no_mutex(void *arg)
{
	struct common_args *args = (struct common_args*)arg;

	uthread_usleep(args->sig_sleep);
	uth_cond_var_lock(args->cv);
	args->flag = TRUE;
	__uth_cond_var_broadcast_and_unlock(args->cv);
	return PTH_TEST_TRUE;
}

static void *__cv_waiter_no_mutex(void *arg)
{
	struct common_args *args = (struct common_args*)arg;

	uthread_usleep(args->wait_sleep);
	uth_cond_var_lock(args->cv);
	while (!args->flag)
		uth_cond_var_wait(args->cv, NULL);
	UT_ASSERT(args->flag);
	uth_cond_var_unlock(args->cv);
	return PTH_TEST_TRUE;
}

bool test_signal_no_mutex(void)
{
	struct common_args local_a, *args = &local_a;
	pthread_t signaller, waiter;
	void *sig_join, *wait_join;
	int ret;
	static uth_cond_var_t static_cv = UTH_COND_VAR_INIT;

	args->cv = &static_cv;
	args->mtx = NULL;

	for (int i = 0; i < 1000; i += 10) {
		args->flag = FALSE;
		args->wait_sleep = i;
		args->sig_sleep = 1000 - i;

		ret = pthread_create(&waiter, 0, __cv_waiter_no_mutex, args);
		UT_ASSERT(!ret);
		ret = pthread_create(&signaller, 0, __cv_signaller_no_mutex,
				     args);
		UT_ASSERT(!ret);
		ret = pthread_join(waiter, &wait_join);
		UT_ASSERT(!ret);
		ret = pthread_join(signaller, &sig_join);
		UT_ASSERT(!ret);
		UT_ASSERT_M("Waiter Failed", wait_join == PTH_TEST_TRUE);
		UT_ASSERT_M("Signaller Failed", sig_join == PTH_TEST_TRUE);
	}

	return TRUE;
}

bool test_broadcast_no_mutex(void)
{
	#define NR_WAITERS 20
	struct common_args local_a, *args = &local_a;
	pthread_t bcaster, waiters[NR_WAITERS];
	void *bcast_join, *wait_joins[NR_WAITERS];
	int ret;

	args->cv = uth_cond_var_alloc();
	args->mtx = NULL;
	args->flag = FALSE;
	args->wait_sleep = 0;
	args->sig_sleep = 1000;

	for (int i = 0; i < NR_WAITERS; i++) {
		ret = pthread_create(&waiters[i], 0, __cv_waiter_no_mutex,
				     args);
		UT_ASSERT(!ret);
	}
	ret = pthread_create(&bcaster, 0, __cv_broadcaster_no_mutex, args);
	UT_ASSERT(!ret);

	ret = pthread_join(bcaster, &bcast_join);
	UT_ASSERT(!ret);
	UT_ASSERT_M("Broadcaster Failed", bcast_join == PTH_TEST_TRUE);
	for (int i = 0; i < NR_WAITERS; i++) {
		ret = pthread_join(waiters[i], &wait_joins[i]);
		UT_ASSERT(!ret);
		UT_ASSERT_M("Waiter Failed", wait_joins[i] == PTH_TEST_TRUE);
	}

	uth_cond_var_free(args->cv);
	return TRUE;
}

static bool __test_recurse(struct uth_recurse_mutex *r_mtx)
{
	bool test;

	uth_recurse_mutex_lock(r_mtx);
	/* should be one lock deep */
	UT_ASSERT(r_mtx->count == 1);
	UT_ASSERT(r_mtx->lockholder == current_uthread);

	test = uth_recurse_mutex_trylock(r_mtx);
	UT_ASSERT_M("Failed to re(try)lock our owned mutex!", test);
	/* should be two locks deep */
	UT_ASSERT(r_mtx->count == 2);
	UT_ASSERT(r_mtx->lockholder == current_uthread);

	uth_recurse_mutex_lock(r_mtx);
	/* should be three locks deep */
	UT_ASSERT(r_mtx->count == 3);
	UT_ASSERT(r_mtx->lockholder == current_uthread);

	uth_recurse_mutex_unlock(r_mtx);
	/* should be two locks deep */
	UT_ASSERT(r_mtx->count == 2);
	UT_ASSERT(r_mtx->lockholder == current_uthread);

	uth_recurse_mutex_unlock(r_mtx);
	/* should be one lock deep */
	UT_ASSERT(r_mtx->count == 1);
	UT_ASSERT(r_mtx->lockholder == current_uthread);

	uth_recurse_mutex_unlock(r_mtx);
	/* should be unlocked */
	UT_ASSERT(r_mtx->count == 0);
	UT_ASSERT(!r_mtx->lockholder);

	return TRUE;
}

bool test_recurse(void)
{
	uth_recurse_mutex_t *r_mtx;

	r_mtx = uth_recurse_mutex_alloc();
	UT_ASSERT(r_mtx);
	if (!__test_recurse(r_mtx))
		return FALSE;
	uth_recurse_mutex_free(r_mtx);

	return TRUE;
}

bool test_recurse_static(void)
{
	static uth_recurse_mutex_t static_recurse_mtx = UTH_RECURSE_MUTEX_INIT;

	return __test_recurse(&static_recurse_mtx);
}

static bool __test_semaphore(struct uth_semaphore *sem, int count)
{
	bool can_down;

	UT_ASSERT(count > 2);	/* for our own use */
	UT_ASSERT(sem->count == count);
	/* should be able to down it count times without blocking */
	for (int i = 0; i < count; i++) {
		uth_semaphore_down(sem);
		UT_ASSERT(sem->count == count - (i + 1));
	}

	/* shouldn't be able to down, since we grabbed them all */
	can_down = uth_semaphore_trydown(sem);
	UT_ASSERT(!can_down);
	UT_ASSERT(sem->count == 0);

	uth_semaphore_up(sem);
	UT_ASSERT(sem->count == 1);
	can_down = uth_semaphore_trydown(sem);
	UT_ASSERT(can_down);
	UT_ASSERT(sem->count == 0);

	for (int i = 0; i < count; i++) {
		uth_semaphore_up(sem);
		UT_ASSERT(sem->count == i + 1);
	}

	return TRUE;
}

bool test_semaphore(void)
{
	uth_semaphore_t *sem;

	sem = uth_semaphore_alloc(5);
	UT_ASSERT(sem);
	if (!__test_semaphore(sem, 5))
		return FALSE;
	uth_semaphore_free(sem);

	return TRUE;
}

bool test_semaphore_static(void)
{
	static uth_semaphore_t static_semaphore = UTH_SEMAPHORE_INIT(5);

	return __test_semaphore(&static_semaphore, 5);
}

bool test_semaphore_timeout(void)
{
	static uth_semaphore_t sem = UTH_SEMAPHORE_INIT(1);
	struct timespec timeout[1];
	int ret;
	bool got_it;

	ret = clock_gettime(CLOCK_REALTIME, timeout);
	UT_ASSERT(!ret);
	timeout->tv_nsec += 500000000;
	got_it = uth_semaphore_timed_down(&sem, timeout);
	UT_ASSERT(got_it);

	/* Second time we still hold the sem and would block and should time
	 * out. */
	UT_ASSERT(sem.count == 0);
	ret = clock_gettime(CLOCK_REALTIME, timeout);
	UT_ASSERT(!ret);
	timeout->tv_nsec += 500000000;
	got_it = uth_semaphore_timed_down(&sem, timeout);
	UT_ASSERT(!got_it);

	return TRUE;
}

bool test_cv_timeout(void)
{
	static uth_mutex_t mtx = UTH_MUTEX_INIT;
	static uth_cond_var_t cv = UTH_COND_VAR_INIT;
	struct timespec timeout[1];
	int ret;
	bool was_signalled;

	uth_mutex_lock(&mtx);
	ret = clock_gettime(CLOCK_REALTIME, timeout);
	UT_ASSERT(!ret);
	timeout->tv_nsec += 500000000;
	was_signalled = uth_cond_var_timed_wait(&cv, &mtx, timeout);
	UT_ASSERT(!was_signalled);
	UT_ASSERT(mtx.count == 0);	/* semaphore's count variable */
	uth_mutex_unlock(&mtx);
	UT_ASSERT(mtx.count == 1);

	return TRUE;
}

bool test_cv_recurse_timeout(void)
{
	static uth_recurse_mutex_t r_mtx = UTH_RECURSE_MUTEX_INIT;
	static uth_cond_var_t cv = UTH_COND_VAR_INIT;
	struct timespec timeout[1];
	int ret;
	bool was_signalled;

	/* Get three-deep locks, make sure the bookkeeping is right */
	uth_recurse_mutex_lock(&r_mtx);
	uth_recurse_mutex_lock(&r_mtx);
	uth_recurse_mutex_lock(&r_mtx);
	UT_ASSERT(r_mtx.count == 3);
	UT_ASSERT(r_mtx.mtx.count == 0);

	ret = clock_gettime(CLOCK_REALTIME, timeout);
	UT_ASSERT(!ret);
	timeout->tv_nsec += 500000000;
	was_signalled = uth_cond_var_timed_wait_recurse(&cv, &r_mtx, timeout);
	UT_ASSERT(!was_signalled);
	UT_ASSERT(r_mtx.count == 3);
	UT_ASSERT(r_mtx.mtx.count == 0);

	/* Unlock our three locks, then make sure the semaphore/mtx is unlocked.
	 */
	uth_recurse_mutex_unlock(&r_mtx);
	uth_recurse_mutex_unlock(&r_mtx);
	uth_recurse_mutex_unlock(&r_mtx);
	UT_ASSERT(r_mtx.count == 0);
	UT_ASSERT(r_mtx.mtx.count == 1);

	return TRUE;
}

bool test_cv_timeout_no_mutex(void)
{
	static uth_cond_var_t cv = UTH_COND_VAR_INIT;
	struct timespec timeout[1];
	int ret;
	bool was_signalled;

	uth_cond_var_lock(&cv);
	ret = clock_gettime(CLOCK_REALTIME, timeout);
	UT_ASSERT(!ret);
	timeout->tv_nsec += 500000000;
	was_signalled = uth_cond_var_timed_wait(&cv, NULL, timeout);
	UT_ASSERT(!was_signalled);
	uth_cond_var_unlock(&cv);

	return TRUE;
}

static uth_rwlock_t rwl = UTH_RWLOCK_INIT;
static int rw_value;

static void *rw_reader(void *arg)
{
	int val;

	uth_rwlock_rdlock(&rwl);
	if (!rw_value) {
		/* We won, let's wait a while to let the writer block (racy) */
		uthread_usleep(5000);
	}
	uth_rwlock_unlock(&rwl);
	while (1) {
		uth_rwlock_rdlock(&rwl);
		val = rw_value;
		uth_rwlock_unlock(&rwl);
		if (val)
			break;
		uthread_usleep(1000);
	}
	return 0;
}

static void *rw_writer(void *arg)
{
	/* Let the readers get a head start */
	uthread_usleep(1000);
	/* This might fail, but can't hurt to try it */
	if (uth_rwlock_try_wrlock(&rwl))
		uth_rwlock_unlock(&rwl);
	/* Eventually we'll get the lock */
	uth_rwlock_wrlock(&rwl);
	rw_value = 1;
	uth_rwlock_unlock(&rwl);
	return 0;
}

bool test_rwlock(void)
{
	#define NR_THREADS 3
	struct uth_join_request joinees[NR_THREADS];
	void *retvals[NR_THREADS];

	joinees[0].uth = uthread_create(rw_reader, NULL);
	joinees[1].uth = uthread_create(rw_reader, NULL);
	joinees[2].uth = uthread_create(rw_writer, NULL);
	for (int i = 0; i < NR_THREADS; i++)
		joinees[i].retval_loc = &retvals[i];
	uthread_join_arr(joinees, NR_THREADS);
	for (int i = 0; i < NR_THREADS; i++)
		UT_ASSERT(retvals[i] == 0);
	return TRUE;
}

/* <--- End definition of test cases ---> */

struct utest utests[] = {
	UTEST_REG(signal_no_wait),
	UTEST_REG(signal),
	UTEST_REG(broadcast),
	UTEST_REG(signal_no_mutex),
	UTEST_REG(broadcast_no_mutex),
	UTEST_REG(recurse),
	UTEST_REG(recurse_static),
	UTEST_REG(semaphore),
	UTEST_REG(semaphore_static),
	UTEST_REG(semaphore_timeout),
	UTEST_REG(cv_timeout),
	UTEST_REG(cv_timeout_no_mutex),
	UTEST_REG(cv_recurse_timeout),
	UTEST_REG(rwlock),
};
int num_utests = sizeof(utests) / sizeof(struct utest);

int main(int argc, char *argv[])
{
	char **whitelist = &argv[1];
	int whitelist_len = argc - 1;

	RUN_TEST_SUITE(utests, num_utests, whitelist, whitelist_len);
}
