/*
 * 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 = ACCESS_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");
}
