/*
 * POWER Data Stream Control Register (DSCR) default test
 *
 * This test modifies the system wide default DSCR through
 * it's sysfs interface and then verifies that all threads
 * see the correct changed DSCR value immediately.
 *
 * Copyright 2012, Anton Blanchard, IBM Corporation.
 * Copyright 2015, Anshuman Khandual, IBM Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */
#include "dscr.h"

static unsigned long dscr;		/* System DSCR default */
static unsigned long sequence;
static unsigned long result[THREADS];

static void *do_test(void *in)
{
	unsigned long thread = (unsigned long)in;
	unsigned long i;

	for (i = 0; i < COUNT; i++) {
		unsigned long d, cur_dscr, cur_dscr_usr;
		unsigned long s1, s2;

		s1 = READ_ONCE(sequence);
		if (s1 & 1)
			continue;
		rmb();

		d = dscr;
		cur_dscr = get_dscr();
		cur_dscr_usr = get_dscr_usr();

		rmb();
		s2 = sequence;

		if (s1 != s2)
			continue;

		if (cur_dscr != d) {
			fprintf(stderr, "thread %ld kernel DSCR should be %ld "
				"but is %ld\n", thread, d, cur_dscr);
			result[thread] = 1;
			pthread_exit(&result[thread]);
		}

		if (cur_dscr_usr != d) {
			fprintf(stderr, "thread %ld user DSCR should be %ld "
				"but is %ld\n", thread, d, cur_dscr_usr);
			result[thread] = 1;
			pthread_exit(&result[thread]);
		}
	}
	result[thread] = 0;
	pthread_exit(&result[thread]);
}

int dscr_default(void)
{
	pthread_t threads[THREADS];
	unsigned long i, *status[THREADS];
	unsigned long orig_dscr_default;

	orig_dscr_default = get_default_dscr();

	/* Initial DSCR default */
	dscr = 1;
	set_default_dscr(dscr);

	/* Spawn all testing threads */
	for (i = 0; i < THREADS; i++) {
		if (pthread_create(&threads[i], NULL, do_test, (void *)i)) {
			perror("pthread_create() failed");
			goto fail;
		}
	}

	srand(getpid());

	/* Keep changing the DSCR default */
	for (i = 0; i < COUNT; i++) {
		double ret = uniform_deviate(rand());

		if (ret < 0.0001) {
			sequence++;
			wmb();

			dscr++;
			if (dscr > DSCR_MAX)
				dscr = 0;

			set_default_dscr(dscr);

			wmb();
			sequence++;
		}
	}

	/* Individual testing thread exit status */
	for (i = 0; i < THREADS; i++) {
		if (pthread_join(threads[i], (void **)&(status[i]))) {
			perror("pthread_join() failed");
			goto fail;
		}

		if (*status[i]) {
			printf("%ldth thread failed to join with %ld status\n",
								i, *status[i]);
			goto fail;
		}
	}
	set_default_dscr(orig_dscr_default);
	return 0;
fail:
	set_default_dscr(orig_dscr_default);
	return 1;
}

int main(int argc, char *argv[])
{
	return test_harness(dscr_default, "dscr_default_test");
}
