aboutsummaryrefslogtreecommitdiffstats
path: root/manual/APPNOTE_011_Design_Investigation/splice.v
blob: 1cf7274c059c5c53a65434dbf696246139a9e18b (plain)
1
2
3
4
5
6
7
8
9
10
module splice_demo(a, b, c, d, e, f, x, y);

input [1:0] a, b, c, d, e, f;
output [1:0] x = {a[0], a[1]};

output [11:0] y;
assign {y[11:4], y[1:0], y[3:2]} =
                {a, b, -{c, d}, ~{e, f}};

endmodule
ghlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* Stress test for Xen Store: multiple people hammering transactions */
#include "xs.h"
#include "utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define NUM_HANDLES 2
#define DIR_FANOUT 3
#define DIR_DEPTH 3

/* How often to print progress */
static int print;

/* Layout looks like /<num>/<num>/count. */
static void work(unsigned int cycles, unsigned int childnum)
{
	unsigned int i;
	struct xs_handle *handles[NUM_HANDLES];
	char id;

	if (childnum < 10)
		id = '0' + childnum;
	else
		id = 'A' + childnum - 10;

	for (i = 0; i < NUM_HANDLES; i++) {
		handles[i] = xs_daemon_open();
		if (!handles[i])
			barf_perror("Opening handle %i", i);
	}

	srandom(childnum);
	for (i = 0; i < cycles; i++) {
		unsigned int j, len;
		char file[100] = "";
		char *contents, tmp[100];
		struct xs_handle *h = handles[random() % NUM_HANDLES];

		for (j = 0; j < DIR_DEPTH; j++)
			sprintf(file + strlen(file), "/%li",
				random()%DIR_FANOUT);

		if (!xs_transaction_start(h))
			barf_perror("%i: starting transaction %i",
				    childnum, i);

		sprintf(file + strlen(file), "/count");
		contents = xs_read(h, file, &len);
		if (!contents)
			barf_perror("%i: can't read %s iter %i",
				    childnum, file, i);
		sprintf(tmp, "%i", atoi(contents) + 1);
		if (!xs_write(h, file, tmp, strlen(tmp)+1))
			barf_perror("%i: can't write %s iter %i",
				    childnum, file, i);

		/* Abandon 1 in 10 */
		if (random() % 10 == 0) {
			if (!xs_transaction_end(h, true))
				barf_perror("%i: can't abort transact",
					    childnum);
			i--;
		} else {
			if (!xs_transaction_end(h, false)) {
				if (errno == EAGAIN) {
					write(STDOUT_FILENO, "!", 1);
					i--;
				} else
					barf_perror("%i: can't commit trans",
						    childnum);
			} else {
				/* Offset when we print . so kids don't all
				 * print at once. */
				if ((i + print/(childnum+1)) % print == 0)
					write(STDOUT_FILENO, &id, 1);
			}
		}
	}
}

static void create_dirs(struct xs_handle *h, const char *base, int togo)
{
	unsigned int i;
	char filename[100];

	if (togo == 0) {
		sprintf(filename, "%s/count", base);
		if (!xs_write(h, filename, "0", 1))
			barf_perror("Writing to %s", filename);
		return;
	}

	for (i = 0; i < DIR_FANOUT; i++) {
		sprintf(filename, "%s/%i", base, i);
		if (!xs_mkdir(h, filename))
			barf_perror("xs_mkdir %s", filename);
		create_dirs(h, filename, togo-1);
	}
}

static unsigned int add_count(struct xs_handle *h, const char *base, int togo)
{
	unsigned int i, count;
	char filename[100];

	if (togo == 0) {
		char *answer;
		unsigned int len;

		sprintf(filename, "%s/count", base);
		answer = xs_read(h, filename, &len);
		if (!answer)
			barf_perror("Reading %s", filename);
		count = atoi(answer);
		free(answer);
		return count;
	}

	count = 0;
	for (i = 0; i < DIR_FANOUT; i++) {
		sprintf(filename, "%s/%i", base, i);
		count += add_count(h, filename, togo-1);
	}
	return count;
}

static void setup(void)
{
	struct xs_handle *h;

	/* Do setup. */
	h = xs_daemon_open();
	if (!h)
		barf_perror("Contacting daemon");
	create_dirs(h, "", DIR_DEPTH);
	xs_daemon_close(h);
}

static unsigned int tally_counts(void)
{
	struct xs_handle *h;
	unsigned int ret;
	
	h = xs_daemon_open();
	if (!h)
		barf_perror("Contacting daemon");

	ret = add_count(h, "", DIR_DEPTH);
	xs_daemon_close(h);
	return ret;
}	

int main(int argc, char *argv[])
{
	unsigned int i;
	bool failed = false;
	int kids[10];

	if (argc != 2)
		barf("Usage: xs_stress <iterations>");

	printf("Setting up directories...\n");
	setup();

	print = atoi(argv[1]) / 76;
	if (!print)
		print = 1;

	printf("Running %i children...\n", ARRAY_SIZE(kids));
	for (i = 0; i < ARRAY_SIZE(kids); i++) {
		kids[i] = fork();
		if (kids[i] == -1)
			barf_perror("fork");
		if (kids[i] == 0) {
			work(atoi(argv[1]) / ARRAY_SIZE(kids), i);
			exit(0);
		}
	}

	for (i = 0; i < ARRAY_SIZE(kids); i++) {
		int status;
		if (waitpid(kids[i], &status, 0) == -1)
			barf_perror("waitpid");
		if (!WIFEXITED(status))
			barf("Kid %i died via signal %i\n",
			     i, WTERMSIG(status));
		if (WEXITSTATUS(status) != 0) {
			printf("Child %i exited %i\n", i, WEXITSTATUS(status));
			failed = true;
		}
	}
	if (failed)
		exit(1);

	printf("\nCounting results...\n");
	i = tally_counts();
	if (i != (unsigned)atoi(argv[1]))
		barf("Total counts %i not %s", i, argv[1]);
	printf("Success!\n");
	exit(0);
}