// SPDX-License-Identifier: GPL-2.0
/*
 * numa.c
 *
 * numa: Simulate NUMA-sensitive workload and measure their NUMA performance
 */

#include <inttypes.h>

#include <subcmd/parse-options.h>
#include "../util/cloexec.h"

#include "bench.h"

#include <errno.h>
#include <sched.h>
#include <stdio.h>
#include <assert.h>
#include <debug.h>
#include <malloc.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <linux/kernel.h>
#include <linux/time64.h>
#include <linux/numa.h>
#include <linux/zalloc.h>

#include "../util/header.h"
#include "../util/mutex.h"
#include <numa.h>
#include <numaif.h>

#ifndef RUSAGE_THREAD
# define RUSAGE_THREAD 1
#endif

/*
 * Regular printout to the terminal, suppressed if -q is specified:
 */
#define tprintf(x...) do { if (g && g->p.show_details >= 0) printf(x); } while (0)

/*
 * Debug printf:
 */
#undef dprintf
#define dprintf(x...) do { if (g && g->p.show_details >= 1) printf(x); } while (0)

struct thread_data {
	int			curr_cpu;
	cpu_set_t		*bind_cpumask;
	int			bind_node;
	u8			*process_data;
	int			process_nr;
	int			thread_nr;
	int			task_nr;
	unsigned int		loops_done;
	u64			val;
	u64			runtime_ns;
	u64			system_time_ns;
	u64			user_time_ns;
	double			speed_gbs;
	struct mutex		*process_lock;
};

/* Parameters set by options: */

struct params {
	/* Startup synchronization: */
	bool			serialize_startup;

	/* Task hierarchy: */
	int			nr_proc;
	int			nr_threads;

	/* Working set sizes: */
	const char		*mb_global_str;
	const char		*mb_proc_str;
	const char		*mb_proc_locked_str;
	const char		*mb_thread_str;

	double			mb_global;
	double			mb_proc;
	double			mb_proc_locked;
	double			mb_thread;

	/* Access patterns to the working set: */
	bool			data_reads;
	bool			data_writes;
	bool			data_backwards;
	bool			data_zero_memset;
	bool			data_rand_walk;
	u32			nr_loops;
	u32			nr_secs;
	u32			sleep_usecs;

	/* Working set initialization: */
	bool			init_zero;
	bool			init_random;
	bool			init_cpu0;

	/* Misc options: */
	int			show_details;
	int			run_all;
	int			thp;

	long			bytes_global;
	long			bytes_process;
	long			bytes_process_locked;
	long			bytes_thread;

	int			nr_tasks;

	bool			show_convergence;
	bool			measure_convergence;

	int			perturb_secs;
	int			nr_cpus;
	int			nr_nodes;

	/* Affinity options -C and -N: */
	char			*cpu_list_str;
	char			*node_list_str;
};


/* Global, read-writable area, accessible to all processes and threads: */

struct global_info {
	u8			*data;

	struct mutex		startup_mutex;
	struct cond		startup_cond;
	int			nr_tasks_started;

	struct mutex		start_work_mutex;
	struct cond		start_work_cond;
	int			nr_tasks_working;
	bool			start_work;

	struct mutex		stop_work_mutex;
	u64			bytes_done;

	struct thread_data	*threads;

	/* Convergence latency measurement: */
	bool			all_converged;
	bool			stop_work;

	int			print_once;

	struct params		p;
};

static struct global_info	*g = NULL;

static int parse_cpus_opt(const struct option *opt, const char *arg, int unset);
static int parse_nodes_opt(const struct option *opt, const char *arg, int unset);

struct params p0;

static const struct option options[] = {
	OPT_INTEGER('p', "nr_proc"	, &p0.nr_proc,		"number of processes"),
	OPT_INTEGER('t', "nr_threads"	, &p0.nr_threads,	"number of threads per process"),

	OPT_STRING('G', "mb_global"	, &p0.mb_global_str,	"MB", "global  memory (MBs)"),
	OPT_STRING('P', "mb_proc"	, &p0.mb_proc_str,	"MB", "process memory (MBs)"),
	OPT_STRING('L', "mb_proc_locked", &p0.mb_proc_locked_str,"MB", "process serialized/locked memory access (MBs), <= process_memory"),
	OPT_STRING('T', "mb_thread"	, &p0.mb_thread_str,	"MB", "thread  memory (MBs)"),

	OPT_UINTEGER('l', "nr_loops"	, &p0.nr_loops,		"max number of loops to run (default: unlimited)"),
	OPT_UINTEGER('s', "nr_secs"	, &p0.nr_secs,		"max number of seconds to run (default: 5 secs)"),
	OPT_UINTEGER('u', "usleep"	, &p0.sleep_usecs,	"usecs to sleep per loop iteration"),

	OPT_BOOLEAN('R', "data_reads"	, &p0.data_reads,	"access the data via reads (can be mixed with -W)"),
	OPT_BOOLEAN('W', "data_writes"	, &p0.data_writes,	"access the data via writes (can be mixed with -R)"),
	OPT_BOOLEAN('B', "data_backwards", &p0.data_backwards,	"access the data backwards as well"),
	OPT_BOOLEAN('Z', "data_zero_memset", &p0.data_zero_memset,"access the data via glibc bzero only"),
	OPT_BOOLEAN('r', "data_rand_walk", &p0.data_rand_walk,	"access the data with random (32bit LFSR) walk"),


	OPT_BOOLEAN('z', "init_zero"	, &p0.init_zero,	"bzero the initial allocations"),
	OPT_BOOLEAN('I', "init_random"	, &p0.init_random,	"randomize the contents of the initial allocations"),
	OPT_BOOLEAN('0', "init_cpu0"	, &p0.init_cpu0,	"do the initial allocations on CPU#0"),
	OPT_INTEGER('x', "perturb_secs", &p0.perturb_secs,	"perturb thread 0/0 every X secs, to test convergence stability"),

	OPT_INCR   ('d', "show_details"	, &p0.show_details,	"Show details"),
	OPT_INCR   ('a', "all"		, &p0.run_all,		"Run all tests in the suite"),
	OPT_INTEGER('H', "thp"		, &p0.thp,		"MADV_NOHUGEPAGE < 0 < MADV_HUGEPAGE"),
	OPT_BOOLEAN('c', "show_convergence", &p0.show_convergence, "show convergence details, "
		    "convergence is reached when each process (all its threads) is running on a single NUMA node."),
	OPT_BOOLEAN('m', "measure_convergence",	&p0.measure_convergence, "measure convergence latency"),
	OPT_BOOLEAN('q', "quiet"	, &quiet,
		    "quiet mode (do not show any warnings or messages)"),
	OPT_BOOLEAN('S', "serialize-startup", &p0.serialize_startup,"serialize thread startup"),

	/* Special option string parsing callbacks: */
        OPT_CALLBACK('C', "cpus", NULL, "cpu[,cpu2,...cpuN]",
			"bind the first N tasks to these specific cpus (the rest is unbound)",
			parse_cpus_opt),
        OPT_CALLBACK('M', "memnodes", NULL, "node[,node2,...nodeN]",
			"bind the first N tasks to these specific memory nodes (the rest is unbound)",
			parse_nodes_opt),
	OPT_END()
};

static const char * const bench_numa_usage[] = {
	"perf bench numa <options>",
	NULL
};

static const char * const numa_usage[] = {
	"perf bench numa mem [<options>]",
	NULL
};

/*
 * To get number of numa nodes present.
 */
static int nr_numa_nodes(void)
{
	int i, nr_nodes = 0;

	for (i = 0; i < g->p.nr_nodes; i++) {
		if (numa_bitmask_isbitset(numa_nodes_ptr, i))
			nr_nodes++;
	}

	return nr_nodes;
}

/*
 * To check if given numa node is present.
 */
static int is_node_present(int node)
{
	return numa_bitmask_isbitset(numa_nodes_ptr, node);
}

/*
 * To check given numa node has cpus.
 */
static bool node_has_cpus(int node)
{
	struct bitmask *cpumask = numa_allocate_cpumask();
	bool ret = false; /* fall back to nocpus */
	int cpu;

	BUG_ON(!cpumask);
	if (!numa_node_to_cpus(node, cpumask)) {
		for (cpu = 0; cpu < (int)cpumask->size; cpu++) {
			if (numa_bitmask_isbitset(cpumask, cpu)) {
				ret = true;
				break;
			}
		}
	}
	numa_free_cpumask(cpumask);

	return ret;
}

static cpu_set_t *bind_to_cpu(int target_cpu)
{
	int nrcpus = numa_num_possible_cpus();
	cpu_set_t *orig_mask, *mask;
	size_t size;

	orig_mask = CPU_ALLOC(nrcpus);
	BUG_ON(!orig_mask);
	size = CPU_ALLOC_SIZE(nrcpus);
	CPU_ZERO_S(size, orig_mask);

	if (sched_getaffinity(0, size, orig_mask))
		goto err_out;

	mask = CPU_ALLOC(nrcpus);
	if (!mask)
		goto err_out;

	CPU_ZERO_S(size, mask);

	if (target_cpu == -1) {
		int cpu;

		for (cpu = 0; cpu < g->p.nr_cpus; cpu++)
			CPU_SET_S(cpu, size, mask);
	} else {
		if (target_cpu < 0 || target_cpu >= g->p.nr_cpus)
			goto err;

		CPU_SET_S(target_cpu, size, mask);
	}

	if (sched_setaffinity(0, size, mask))
		goto err;

	return orig_mask;

err:
	CPU_FREE(mask);
err_out:
	CPU_FREE(orig_mask);

	/* BUG_ON due to failure in allocation of orig_mask/mask */
	BUG_ON(-1);
	return NULL;
}

static cpu_set_t *bind_to_node(int target_node)
{
	int nrcpus = numa_num_possible_cpus();
	size_t size;
	cpu_set_t *orig_mask, *mask;
	int cpu;

	orig_mask = CPU_ALLOC(nrcpus);
	BUG_ON(!orig_mask);
	size = CPU_ALLOC_SIZE(nrcpus);
	CPU_ZERO_S(size, orig_mask);

	if (sched_getaffinity(0, size, orig_mask))
		goto err_out;

	mask = CPU_ALLOC(nrcpus);
	if (!mask)
		goto err_out;

	CPU_ZERO_S(size, mask);

	if (target_node == NUMA_NO_NODE) {
		for (cpu = 0; cpu < g->p.nr_cpus; cpu++)
			CPU_SET_S(cpu, size, mask);
	} else {
		struct bitmask *cpumask = numa_allocate_cpumask();

		if (!cpumask)
			goto err;

		if (!numa_node_to_cpus(target_node, cpumask)) {
			for (cpu = 0; cpu < (int)cpumask->size; cpu++) {
				if (numa_bitmask_isbitset(cpumask, cpu))
					CPU_SET_S(cpu, size, mask);
			}
		}
		numa_free_cpumask(cpumask);
	}

	if (sched_setaffinity(0, size, mask))
		goto err;

	return orig_mask;

err:
	CPU_FREE(mask);
err_out:
	CPU_FREE(orig_mask);

	/* BUG_ON due to failure in allocation of orig_mask/mask */
	BUG_ON(-1);
	return NULL;
}

static void bind_to_cpumask(cpu_set_t *mask)
{
	int ret;
	size_t size = CPU_ALLOC_SIZE(numa_num_possible_cpus());

	ret = sched_setaffinity(0, size, mask);
	if (ret) {
		CPU_FREE(mask);
		BUG_ON(ret);
	}
}

static void mempol_restore(void)
{
	int ret;

	ret = set_mempolicy(MPOL_DEFAULT, NULL, g->p.nr_nodes-1);

	BUG_ON(ret);
}

static void bind_to_memnode(int node)
{
	struct bitmask *node_mask;
	int ret;

	if (node == NUMA_NO_NODE)
		return;

	node_mask = numa_allocate_nodemask();
	BUG_ON(!node_mask);

	numa_bitmask_clearall(node_mask);
	numa_bitmask_setbit(node_mask, node);

	ret = set_mempolicy(MPOL_BIND, node_mask->maskp, node_mask->size + 1);
	dprintf("binding to node %d, mask: %016lx => %d\n", node, *node_mask->maskp, ret);

	numa_bitmask_free(node_mask);
	BUG_ON(ret);
}

#define HPSIZE (2*1024*1024)

#define set_taskname(fmt...)				\
do {							\
	char name[20];					\
							\
	snprintf(name, 20, fmt);			\
	prctl(PR_SET_NAME, name);			\
} while (0)

static u8 *alloc_data(ssize_t bytes0, int map_flags,
		      int init_zero, int init_cpu0, int thp, int init_random)
{
	cpu_set_t *orig_mask = NULL;
	ssize_t bytes;
	u8 *buf;
	int ret;

	if (!bytes0)
		return NULL;

	/* Allocate and initialize all memory on CPU#0: */
	if (init_cpu0) {
		int node = numa_node_of_cpu(0);

		orig_mask = bind_to_node(node);
		bind_to_memnode(node);
	}

	bytes = bytes0 + HPSIZE;

	buf = (void *)mmap(0, bytes, PROT_READ|PROT_WRITE, MAP_ANON|map_flags, -1, 0);
	BUG_ON(buf == (void *)-1);

	if (map_flags == MAP_PRIVATE) {
		if (thp > 0) {
			ret = madvise(buf, bytes, MADV_HUGEPAGE);
			if (ret && !g->print_once) {
				g->print_once = 1;
				printf("WARNING: Could not enable THP - do: 'echo madvise > /sys/kernel/mm/transparent_hugepage/enabled'\n");
			}
		}
		if (thp < 0) {
			ret = madvise(buf, bytes, MADV_NOHUGEPAGE);
			if (ret && !g->print_once) {
				g->print_once = 1;
				printf("WARNING: Could not disable THP: run a CONFIG_TRANSPARENT_HUGEPAGE kernel?\n");
			}
		}
	}

	if (init_zero) {
		bzero(buf, bytes);
	} else {
		/* Initialize random contents, different in each word: */
		if (init_random) {
			u64 *wbuf = (void *)buf;
			long off = rand();
			long i;

			for (i = 0; i < bytes/8; i++)
				wbuf[i] = i + off;
		}
	}

	/* Align to 2MB boundary: */
	buf = (void *)(((unsigned long)buf + HPSIZE-1) & ~(HPSIZE-1));

	/* Restore affinity: */
	if (init_cpu0) {
		bind_to_cpumask(orig_mask);
		CPU_FREE(orig_mask);
		mempol_restore();
	}

	return buf;
}

static void free_data(void *data, ssize_t bytes)
{
	int ret;

	if (!data)
		return;

	ret = munmap(data, bytes);
	BUG_ON(ret);
}

/*
 * Create a shared memory buffer that can be shared between processes, zeroed:
 */
static void * zalloc_shared_data(ssize_t bytes)
{
	return alloc_data(bytes, MAP_SHARED, 1, g->p.init_cpu0,  g->p.thp, g->p.init_random);
}

/*
 * Create a shared memory buffer that can be shared between processes:
 */
static void * setup_shared_data(ssize_t bytes)
{
	return alloc_data(bytes, MAP_SHARED, 0, g->p.init_cpu0,  g->p.thp, g->p.init_random);
}

/*
 * Allocate process-local memory - this will either be shared between
 * threads of this process, or only be accessed by this thread:
 */
static void * setup_private_data(ssize_t bytes)
{
	return alloc_data(bytes, MAP_PRIVATE, 0, g->p.init_cpu0,  g->p.thp, g->p.init_random);
}

static int parse_cpu_list(const char *arg)
{
	p0.cpu_list_str = strdup(arg);

	dprintf("got CPU list: {%s}\n", p0.cpu_list_str);

	return 0;
}

static int parse_setup_cpu_list(void)
{
	struct thread_data *td;
	char *str0, *str;
	int t;

	if (!g->p.cpu_list_str)
		return 0;

	dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks);

	str0 = str = strdup(g->p.cpu_list_str);
	t = 0;

	BUG_ON(!str);

	tprintf("# binding tasks to CPUs:\n");
	tprintf("#  ");

	while (true) {
		int bind_cpu, bind_cpu_0, bind_cpu_1;
		char *tok, *tok_end, *tok_step, *tok_len, *tok_mul;
		int bind_len;
		int step;
		int mul;

		tok = strsep(&str, ",");
		if (!tok)
			break;

		tok_end = strstr(tok, "-");

		dprintf("\ntoken: {%s}, end: {%s}\n", tok, tok_end);
		if (!tok_end) {
			/* Single CPU specified: */
			bind_cpu_0 = bind_cpu_1 = atol(tok);
		} else {
			/* CPU range specified (for example: "5-11"): */
			bind_cpu_0 = atol(tok);
			bind_cpu_1 = atol(tok_end + 1);
		}

		step = 1;
		tok_step = strstr(tok, "#");
		if (tok_step) {
			step = atol(tok_step + 1);
			BUG_ON(step <= 0 || step >= g->p.nr_cpus);
		}

		/*
		 * Mask length.
		 * Eg: "--cpus 8_4-16#4" means: '--cpus 8_4,12_4,16_4',
		 * where the _4 means the next 4 CPUs are allowed.
		 */
		bind_len = 1;
		tok_len = strstr(tok, "_");
		if (tok_len) {
			bind_len = atol(tok_len + 1);
			BUG_ON(bind_len <= 0 || bind_len > g->p.nr_cpus);
		}

		/* Multiplicator shortcut, "0x8" is a shortcut for: "0,0,0,0,0,0,0,0" */
		mul = 1;
		tok_mul = strstr(tok, "x");
		if (tok_mul) {
			mul = atol(tok_mul + 1);
			BUG_ON(mul <= 0);
		}

		dprintf("CPUs: %d_%d-%d#%dx%d\n", bind_cpu_0, bind_len, bind_cpu_1, step, mul);

		if (bind_cpu_0 >= g->p.nr_cpus || bind_cpu_1 >= g->p.nr_cpus) {
			printf("\nTest not applicable, system has only %d CPUs.\n", g->p.nr_cpus);
			return -1;
		}

		if (is_cpu_online(bind_cpu_0) != 1 || is_cpu_online(bind_cpu_1) != 1) {
			printf("\nTest not applicable, bind_cpu_0 or bind_cpu_1 is offline\n");
			return -1;
		}

		BUG_ON(bind_cpu_0 < 0 || bind_cpu_1 < 0);
		BUG_ON(bind_cpu_0 > bind_cpu_1);

		for (bind_cpu = bind_cpu_0; bind_cpu <= bind_cpu_1; bind_cpu += step) {
			size_t size = CPU_ALLOC_SIZE(g->p.nr_cpus);
			int i;

			for (i = 0; i < mul; i++) {
				int cpu;

				if (t >= g->p.nr_tasks) {
					printf("\n# NOTE: ignoring bind CPUs starting at CPU#%d\n #", bind_cpu);
					goto out;
				}
				td = g->threads + t;

				if (t)
					tprintf(",");
				if (bind_len > 1) {
					tprintf("%2d/%d", bind_cpu, bind_len);
				} else {
					tprintf("%2d", bind_cpu);
				}

				td->bind_cpumask = CPU_ALLOC(g->p.nr_cpus);
				BUG_ON(!td->bind_cpumask);
				CPU_ZERO_S(size, td->bind_cpumask);
				for (cpu = bind_cpu; cpu < bind_cpu+bind_len; cpu++) {
					if (cpu < 0 || cpu >= g->p.nr_cpus) {
						CPU_FREE(td->bind_cpumask);
						BUG_ON(-1);
					}
					CPU_SET_S(cpu, size, td->bind_cpumask);
				}
				t++;
			}
		}
	}
out:

	tprintf("\n");

	if (t < g->p.nr_tasks)
		printf("# NOTE: %d tasks bound, %d tasks unbound\n", t, g->p.nr_tasks - t);

	free(str0);
	return 0;
}

static int parse_cpus_opt(const struct option *opt __maybe_unused,
			  const char *arg, int unset __maybe_unused)
{
	if (!arg)
		return -1;

	return parse_cpu_list(arg);
}

static int parse_node_list(const char *arg)
{
	p0.node_list_str = strdup(arg);

	dprintf("got NODE list: {%s}\n", p0.node_list_str);

	return 0;
}

static int parse_setup_node_list(void)
{
	struct thread_data *td;
	char *str0, *str;
	int t;

	if (!g->p.node_list_str)
		return 0;

	dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks);

	str0 = str = strdup(g->p.node_list_str);
	t = 0;

	BUG_ON(!str);

	tprintf("# binding tasks to NODEs:\n");
	tprintf("# ");

	while (true) {
		int bind_node, bind_node_0, bind_node_1;
		char *tok, *tok_end, *tok_step, *tok_mul;
		int step;
		int mul;

		tok = strsep(&str, ",");
		if (!tok)
			break;

		tok_end = strstr(tok, "-");

		dprintf("\ntoken: {%s}, end: {%s}\n", tok, tok_end);
		if (!tok_end) {
			/* Single NODE specified: */
			bind_node_0 = bind_node_1 = atol(tok);
		} else {
			/* NODE range specified (for example: "5-11"): */
			bind_node_0 = atol(tok);
			bind_node_1 = atol(tok_end + 1);
		}

		step = 1;
		tok_step = strstr(tok, "#");
		if (tok_step) {
			step = atol(tok_step + 1);
			BUG_ON(step <= 0 || step >= g->p.nr_nodes);
		}

		/* Multiplicator shortcut, "0x8" is a shortcut for: "0,0,0,0,0,0,0,0" */
		mul = 1;
		tok_mul = strstr(tok, "x");
		if (tok_mul) {
			mul = atol(tok_mul + 1);
			BUG_ON(mul <= 0);
		}

		dprintf("NODEs: %d-%d #%d\n", bind_node_0, bind_node_1, step);

		if (bind_node_0 >= g->p.nr_nodes || bind_node_1 >= g->p.nr_nodes) {
			printf("\nTest not applicable, system has only %d nodes.\n", g->p.nr_nodes);
			return -1;
		}

		BUG_ON(bind_node_0 < 0 || bind_node_1 < 0);
		BUG_ON(bind_node_0 > bind_node_1);

		for (bind_node = bind_node_0; bind_node <= bind_node_1; bind_node += step) {
			int i;

			for (i = 0; i < mul; i++) {
				if (t >= g->p.nr_tasks || !node_has_cpus(bind_node)) {
					printf("\n# NOTE: ignoring bind NODEs starting at NODE#%d\n", bind_node);
					goto out;
				}
				td = g->threads + t;

				if (!t)
					tprintf(" %2d", bind_node);
				else
					tprintf(",%2d", bind_node);

				td->bind_node = bind_node;
				t++;
			}
		}
	}
out:

	tprintf("\n");

	if (t < g->p.nr_tasks)
		printf("# NOTE: %d tasks mem-bound, %d tasks unbound\n", t, g->p.nr_tasks - t);

	free(str0);
	return 0;
}

static int parse_nodes_opt(const struct option *opt __maybe_unused,
			  const char *arg, int unset __maybe_unused)
{
	if (!arg)
		return -1;

	return parse_node_list(arg);
}

static inline uint32_t lfsr_32(uint32_t lfsr)
{
	const uint32_t taps = BIT(1) | BIT(5) | BIT(6) | BIT(31);
	return (lfsr>>1) ^ ((0x0u - (lfsr & 0x1u)) & taps);
}

/*
 * Make sure there's real data dependency to RAM (when read
 * accesses are enabled), so the compiler, the CPU and the
 * kernel (KSM, zero page, etc.) cannot optimize away RAM
 * accesses:
 */
static inline u64 access_data(u64 *data, u64 val)
{
	if (g->p.data_reads)
		val += *data;
	if (g->p.data_writes)
		*data = val + 1;
	return val;
}

/*
 * The worker process does two types of work, a forwards going
 * loop and a backwards going loop.
 *
 * We do this so that on multiprocessor systems we do not create
 * a 'train' of processing, with highly synchronized processes,
 * skewing the whole benchmark.
 */
static u64 do_work(u8 *__data, long bytes, int nr, int nr_max, int loop, u64 val)
{
	long words = bytes/sizeof(u64);
	u64 *data = (void *)__data;
	long chunk_0, chunk_1;
	u64 *d0, *d, *d1;
	long off;
	long i;

	BUG_ON(!data && words);
	BUG_ON(data && !words);

	if (!data)
		return val;

	/* Very simple memset() work variant: */
	if (g->p.data_zero_memset && !g->p.data_rand_walk) {
		bzero(data, bytes);
		return val;
	}

	/* Spread out by PID/TID nr and by loop nr: */
	chunk_0 = words/nr_max;
	chunk_1 = words/g->p.nr_loops;
	off = nr*chunk_0 + loop*chunk_1;

	while (off >= words)
		off -= words;

	if (g->p.data_rand_walk) {
		u32 lfsr = nr + loop + val;
		int j;

		for (i = 0; i < words/1024; i++) {
			long start, end;

			lfsr = lfsr_32(lfsr);

			start = lfsr % words;
			end = min(start + 1024, words-1);

			if (g->p.data_zero_memset) {
				bzero(data + start, (end-start) * sizeof(u64));
			} else {
				for (j = start; j < end; j++)
					val = access_data(data + j, val);
			}
		}
	} else if (!g->p.data_backwards || (nr + loop) & 1) {
		/* Process data forwards: */

		d0 = data + off;
		d  = data + off + 1;
		d1 = data + words;

		for (;;) {
			if (unlikely(d >= d1))
				d = data;
			if (unlikely(d == d0))
				break;

			val = access_data(d, val);

			d++;
		}
	} else {
		/* Process data backwards: */

		d0 = data + off;
		d  = data + off - 1;
		d1 = data + words;

		for (;;) {
			if (unlikely(d < data))
				d = data + words-1;
			if (unlikely(d == d0))
				break;

			val = access_data(d, val);

			d--;
		}
	}

	return val;
}

static void update_curr_cpu(int task_nr, unsigned long bytes_worked)
{
	unsigned int cpu;

	cpu = sched_getcpu();

	g->threads[task_nr].curr_cpu = cpu;
	prctl(0, bytes_worked);
}

/*
 * Count the number of nodes a process's threads
 * are spread out on.
 *
 * A count of 1 means that the process is compressed
 * to a single node. A count of g->p.nr_nodes means it's
 * spread out on the whole system.
 */
static int count_process_nodes(int process_nr)
{
	char *node_present;
	int nodes;
	int n, t;

	node_present = (char *)malloc(g->p.nr_nodes * sizeof(char));
	BUG_ON(!node_present);
	for (nodes = 0; nodes < g->p.nr_nodes; nodes++)
		node_present[nodes] = 0;

	for (t = 0; t < g->p.nr_threads; t++) {
		struct thread_data *td;
		int task_nr;
		int node;

		task_nr = process_nr*g->p.nr_threads + t;
		td = g->threads + task_nr;

		node = numa_node_of_cpu(td->curr_cpu);
		if (node < 0) /* curr_cpu was likely still -1 */ {
			free(node_present);
			return 0;
		}

		node_present[node] = 1;
	}

	nodes = 0;

	for (n = 0; n < g->p.nr_nodes; n++)
		nodes += node_present[n];

	free(node_present);
	return nodes;
}

/*
 * Count the number of distinct process-threads a node contains.
 *
 * A count of 1 means that the node contains only a single
 * process. If all nodes on the system contain at most one
 * process then we are well-converged.
 */
static int count_node_processes(int node)
{
	int processes = 0;
	int t, p;

	for (p = 0; p < g->p.nr_proc; p++) {
		for (t = 0; t < g->p.nr_threads; t++) {
			struct thread_data *td;
			int task_nr;
			int n;

			task_nr = p*g->p.nr_threads + t;
			td = g->threads + task_nr;

			n = numa_node_of_cpu(td->curr_cpu);
			if (n == node) {
				processes++;
				break;
			}
		}
	}

	return processes;
}

static void calc_convergence_compression(int *strong)
{
	unsigned int nodes_min, nodes_max;
	int p;

	nodes_min = -1;
	nodes_max =  0;

	for (p = 0; p < g->p.nr_proc; p++) {
		unsigned int nodes = count_process_nodes(p);

		if (!nodes) {
			*strong = 0;
			return;
		}

		nodes_min = min(nodes, nodes_min);
		nodes_max = max(nodes, nodes_max);
	}

	/* Strong convergence: all threads compress on a single node: */
	if (nodes_min == 1 && nodes_max == 1) {
		*strong = 1;
	} else {
		*strong = 0;
		tprintf(" {%d-%d}", nodes_min, nodes_max);
	}
}

static void calc_convergence(double runtime_ns_max, double *convergence)
{
	unsigned int loops_done_min, loops_done_max;
	int process_groups;
	int *nodes;
	int distance;
	int nr_min;
	int nr_max;
	int strong;
	int sum;
	int nr;
	int node;
	int cpu;
	int t;

	if (!g->p.show_convergence && !g->p.measure_convergence)
		return;

	nodes = (int *)malloc(g->p.nr_nodes * sizeof(int));
	BUG_ON(!nodes);
	for (node = 0; node < g->p.nr_nodes; node++)
		nodes[node] = 0;

	loops_done_min = -1;
	loops_done_max = 0;

	for (t = 0; t < g->p.nr_tasks; t++) {
		struct thread_data *td = g->threads + t;
		unsigned int loops_done;

		cpu = td->curr_cpu;

		/* Not all threads have written it yet: */
		if (cpu < 0)
			continue;

		node = numa_node_of_cpu(cpu);

		nodes[node]++;

		loops_done = td->loops_done;
		loops_done_min = min(loops_done, loops_done_min);
		loops_done_max = max(loops_done, loops_done_max);
	}

	nr_max = 0;
	nr_min = g->p.nr_tasks;
	sum = 0;

	for (node = 0; node < g->p.nr_nodes; node++) {
		if (!is_node_present(node))
			continue;
		nr = nodes[node];
		nr_min = min(nr, nr_min);
		nr_max = max(nr, nr_max);
		sum += nr;
	}
	BUG_ON(nr_min > nr_max);

	BUG_ON(sum > g->p.nr_tasks);

	if (0 && (sum < g->p.nr_tasks)) {
		free(nodes);
		return;
	}

	/*
	 * Count the number of distinct process groups present
	 * on nodes - when we are converged this will decrease
	 * to g->p.nr_proc:
	 */
	process_groups = 0;

	for (node = 0; node < g->p.nr_nodes; node++) {
		int processes;

		if (!is_node_present(node))
			continue;
		processes = count_node_processes(node);
		nr = nodes[node];
		tprintf(" %2d/%-2d", nr, processes);

		process_groups += processes;
	}

	distance = nr_max - nr_min;

	tprintf(" [%2d/%-2d]", distance, process_groups);

	tprintf(" l:%3d-%-3d (%3d)",
		loops_done_min, loops_done_max, loops_done_max-loops_done_min);

	if (loops_done_min && loops_done_max) {
		double skew = 1.0 - (double)loops_done_min/loops_done_max;

		tprintf(" [%4.1f%%]", skew * 100.0);
	}

	calc_convergence_compression(&strong);

	if (strong && process_groups == g->p.nr_proc) {
		if (!*convergence) {
			*convergence = runtime_ns_max;
			tprintf(" (%6.1fs converged)\n", *convergence / NSEC_PER_SEC);
			if (g->p.measure_convergence) {
				g->all_converged = true;
				g->stop_work = true;
			}
		}
	} else {
		if (*convergence) {
			tprintf(" (%6.1fs de-converged)", runtime_ns_max / NSEC_PER_SEC);
			*convergence = 0;
		}
		tprintf("\n");
	}

	free(nodes);
}

static void show_summary(double runtime_ns_max, int l, double *convergence)
{
	tprintf("\r #  %5.1f%%  [%.1f mins]",
		(double)(l+1)/g->p.nr_loops*100.0, runtime_ns_max / NSEC_PER_SEC / 60.0);

	calc_convergence(runtime_ns_max, convergence);

	if (g->p.show_details >= 0)
		fflush(stdout);
}

static void *worker_thread(void *__tdata)
{
	struct thread_data *td = __tdata;
	struct timeval start0, start, stop, diff;
	int process_nr = td->process_nr;
	int thread_nr = td->thread_nr;
	unsigned long last_perturbance;
	int task_nr = td->task_nr;
	int details = g->p.show_details;
	int first_task, last_task;
	double convergence = 0;
	u64 val = td->val;
	double runtime_ns_max;
	u8 *global_data;
	u8 *process_data;
	u8 *thread_data;
	u64 bytes_done, secs;
	long work_done;
	u32 l;
	struct rusage rusage;

	bind_to_cpumask(td->bind_cpumask);
	bind_to_memnode(td->bind_node);

	set_taskname("thread %d/%d", process_nr, thread_nr);

	global_data = g->data;
	process_data = td->process_data;
	thread_data = setup_private_data(g->p.bytes_thread);

	bytes_done = 0;

	last_task = 0;
	if (process_nr == g->p.nr_proc-1 && thread_nr == g->p.nr_threads-1)
		last_task = 1;

	first_task = 0;
	if (process_nr == 0 && thread_nr == 0)
		first_task = 1;

	if (details >= 2) {
		printf("#  thread %2d / %2d global mem: %p, process mem: %p, thread mem: %p\n",
			process_nr, thread_nr, global_data, process_data, thread_data);
	}

	if (g->p.serialize_startup) {
		mutex_lock(&g->startup_mutex);
		g->nr_tasks_started++;
		/* The last thread wakes the main process. */
		if (g->nr_tasks_started == g->p.nr_tasks)
			cond_signal(&g->startup_cond);

		mutex_unlock(&g->startup_mutex);

		/* Here we will wait for the main process to start us all at once: */
		mutex_lock(&g->start_work_mutex);
		g->start_work = false;
		g->nr_tasks_working++;
		while (!g->start_work)
			cond_wait(&g->start_work_cond, &g->start_work_mutex);

		mutex_unlock(&g->start_work_mutex);
	}

	gettimeofday(&start0, NULL);

	start = stop = start0;
	last_perturbance = start.tv_sec;

	for (l = 0; l < g->p.nr_loops; l++) {
		start = stop;

		if (g->stop_work)
			break;

		val += do_work(global_data,  g->p.bytes_global,  process_nr, g->p.nr_proc,	l, val);
		val += do_work(process_data, g->p.bytes_process, thread_nr,  g->p.nr_threads,	l, val);
		val += do_work(thread_data,  g->p.bytes_thread,  0,          1,		l, val);

		if (g->p.sleep_usecs) {
			mutex_lock(td->process_lock);
			usleep(g->p.sleep_usecs);
			mutex_unlock(td->process_lock);
		}
		/*
		 * Amount of work to be done under a process-global lock:
		 */
		if (g->p.bytes_process_locked) {
			mutex_lock(td->process_lock);
			val += do_work(process_data, g->p.bytes_process_locked, thread_nr,  g->p.nr_threads,	l, val);
			mutex_unlock(td->process_lock);
		}

		work_done = g->p.bytes_global + g->p.bytes_process +
			    g->p.bytes_process_locked + g->p.bytes_thread;

		update_curr_cpu(task_nr, work_done);
		bytes_done += work_done;

		if (details < 0 && !g->p.perturb_secs && !g->p.measure_convergence && !g->p.nr_secs)
			continue;

		td->loops_done = l;

		gettimeofday(&stop, NULL);

		/* Check whether our max runtime timed out: */
		if (g->p.nr_secs) {
			timersub(&stop, &start0, &diff);
			if ((u32)diff.tv_sec >= g->p.nr_secs) {
				g->stop_work = true;
				break;
			}
		}

		/* Update the summary at most once per second: */
		if (start.tv_sec == stop.tv_sec)
			continue;

		/*
		 * Perturb the first task's equilibrium every g->p.perturb_secs seconds,
		 * by migrating to CPU#0:
		 */
		if (first_task && g->p.perturb_secs && (int)(stop.tv_sec - last_perturbance) >= g->p.perturb_secs) {
			cpu_set_t *orig_mask;
			int target_cpu;
			int this_cpu;

			last_perturbance = stop.tv_sec;

			/*
			 * Depending on where we are running, move into
			 * the other half of the system, to create some
			 * real disturbance:
			 */
			this_cpu = g->threads[task_nr].curr_cpu;
			if (this_cpu < g->p.nr_cpus/2)
				target_cpu = g->p.nr_cpus-1;
			else
				target_cpu = 0;

			orig_mask = bind_to_cpu(target_cpu);

			/* Here we are running on the target CPU already */
			if (details >= 1)
				printf(" (injecting perturbalance, moved to CPU#%d)\n", target_cpu);

			bind_to_cpumask(orig_mask);
			CPU_FREE(orig_mask);
		}

		if (details >= 3) {
			timersub(&stop, &start, &diff);
			runtime_ns_max = diff.tv_sec * NSEC_PER_SEC;
			runtime_ns_max += diff.tv_usec * NSEC_PER_USEC;

			if (details >= 0) {
				printf(" #%2d / %2d: %14.2lf nsecs/op [val: %016"PRIx64"]\n",
					process_nr, thread_nr, runtime_ns_max / bytes_done, val);
			}
			fflush(stdout);
		}
		if (!last_task)
			continue;

		timersub(&stop, &start0, &diff);
		runtime_ns_max = diff.tv_sec * NSEC_PER_SEC;
		runtime_ns_max += diff.tv_usec * NSEC_PER_USEC;

		show_summary(runtime_ns_max, l, &convergence);
	}

	gettimeofday(&stop, NULL);
	timersub(&stop, &start0, &diff);
	td->runtime_ns = diff.tv_sec * NSEC_PER_SEC;
	td->runtime_ns += diff.tv_usec * NSEC_PER_USEC;
	secs = td->runtime_ns / NSEC_PER_SEC;
	td->speed_gbs = secs ? bytes_done / secs / 1e9 : 0;

	getrusage(RUSAGE_THREAD, &rusage);
	td->system_time_ns = rusage.ru_stime.tv_sec * NSEC_PER_SEC;
	td->system_time_ns += rusage.ru_stime.tv_usec * NSEC_PER_USEC;
	td->user_time_ns = rusage.ru_utime.tv_sec * NSEC_PER_SEC;
	td->user_time_ns += rusage.ru_utime.tv_usec * NSEC_PER_USEC;

	free_data(thread_data, g->p.bytes_thread);

	mutex_lock(&g->stop_work_mutex);
	g->bytes_done += bytes_done;
	mutex_unlock(&g->stop_work_mutex);

	return NULL;
}

/*
 * A worker process starts a couple of threads:
 */
static void worker_process(int process_nr)
{
	struct mutex process_lock;
	struct thread_data *td;
	pthread_t *pthreads;
	u8 *process_data;
	int task_nr;
	int ret;
	int t;

	mutex_init(&process_lock);
	set_taskname("process %d", process_nr);

	/*
	 * Pick up the memory policy and the CPU binding of our first thread,
	 * so that we initialize memory accordingly:
	 */
	task_nr = process_nr*g->p.nr_threads;
	td = g->threads + task_nr;

	bind_to_memnode(td->bind_node);
	bind_to_cpumask(td->bind_cpumask);

	pthreads = zalloc(g->p.nr_threads * sizeof(pthread_t));
	process_data = setup_private_data(g->p.bytes_process);

	if (g->p.show_details >= 3) {
		printf(" # process %2d global mem: %p, process mem: %p\n",
			process_nr, g->data, process_data);
	}

	for (t = 0; t < g->p.nr_threads; t++) {
		task_nr = process_nr*g->p.nr_threads + t;
		td = g->threads + task_nr;

		td->process_data = process_data;
		td->process_nr   = process_nr;
		td->thread_nr    = t;
		td->task_nr	 = task_nr;
		td->val          = rand();
		td->curr_cpu	 = -1;
		td->process_lock = &process_lock;

		ret = pthread_create(pthreads + t, NULL, worker_thread, td);
		BUG_ON(ret);
	}

	for (t = 0; t < g->p.nr_threads; t++) {
                ret = pthread_join(pthreads[t], NULL);
		BUG_ON(ret);
	}

	free_data(process_data, g->p.bytes_process);
	free(pthreads);
}

static void print_summary(void)
{
	if (g->p.show_details < 0)
		return;

	printf("\n ###\n");
	printf(" # %d %s will execute (on %d nodes, %d CPUs):\n",
		g->p.nr_tasks, g->p.nr_tasks == 1 ? "task" : "tasks", nr_numa_nodes(), g->p.nr_cpus);
	printf(" #      %5dx %5ldMB global  shared mem operations\n",
			g->p.nr_loops, g->p.bytes_global/1024/1024);
	printf(" #      %5dx %5ldMB process shared mem operations\n",
			g->p.nr_loops, g->p.bytes_process/1024/1024);
	printf(" #      %5dx %5ldMB thread  local  mem operations\n",
			g->p.nr_loops, g->p.bytes_thread/1024/1024);

	printf(" ###\n");

	printf("\n ###\n"); fflush(stdout);
}

static void init_thread_data(void)
{
	ssize_t size = sizeof(*g->threads)*g->p.nr_tasks;
	int t;

	g->threads = zalloc_shared_data(size);

	for (t = 0; t < g->p.nr_tasks; t++) {
		struct thread_data *td = g->threads + t;
		size_t cpuset_size = CPU_ALLOC_SIZE(g->p.nr_cpus);
		int cpu;

		/* Allow all nodes by default: */
		td->bind_node = NUMA_NO_NODE;

		/* Allow all CPUs by default: */
		td->bind_cpumask = CPU_ALLOC(g->p.nr_cpus);
		BUG_ON(!td->bind_cpumask);
		CPU_ZERO_S(cpuset_size, td->bind_cpumask);
		for (cpu = 0; cpu < g->p.nr_cpus; cpu++)
			CPU_SET_S(cpu, cpuset_size, td->bind_cpumask);
	}
}

static void deinit_thread_data(void)
{
	ssize_t size = sizeof(*g->threads)*g->p.nr_tasks;
	int t;

	/* Free the bind_cpumask allocated for thread_data */
	for (t = 0; t < g->p.nr_tasks; t++) {
		struct thread_data *td = g->threads + t;
		CPU_FREE(td->bind_cpumask);
	}

	free_data(g->threads, size);
}

static int init(void)
{
	g = (void *)alloc_data(sizeof(*g), MAP_SHARED, 1, 0, 0 /* THP */, 0);

	/* Copy over options: */
	g->p = p0;

	g->p.nr_cpus = numa_num_configured_cpus();

	g->p.nr_nodes = numa_max_node() + 1;

	/* char array in count_process_nodes(): */
	BUG_ON(g->p.nr_nodes < 0);

	if (quiet && !g->p.show_details)
		g->p.show_details = -1;

	/* Some memory should be specified: */
	if (!g->p.mb_global_str && !g->p.mb_proc_str && !g->p.mb_thread_str)
		return -1;

	if (g->p.mb_global_str) {
		g->p.mb_global = atof(g->p.mb_global_str);
		BUG_ON(g->p.mb_global < 0);
	}

	if (g->p.mb_proc_str) {
		g->p.mb_proc = atof(g->p.mb_proc_str);
		BUG_ON(g->p.mb_proc < 0);
	}

	if (g->p.mb_proc_locked_str) {
		g->p.mb_proc_locked = atof(g->p.mb_proc_locked_str);
		BUG_ON(g->p.mb_proc_locked < 0);
		BUG_ON(g->p.mb_proc_locked > g->p.mb_proc);
	}

	if (g->p.mb_thread_str) {
		g->p.mb_thread = atof(g->p.mb_thread_str);
		BUG_ON(g->p.mb_thread < 0);
	}

	BUG_ON(g->p.nr_threads <= 0);
	BUG_ON(g->p.nr_proc <= 0);

	g->p.nr_tasks = g->p.nr_proc*g->p.nr_threads;

	g->p.bytes_global		= g->p.mb_global	*1024L*1024L;
	g->p.bytes_process		= g->p.mb_proc		*1024L*1024L;
	g->p.bytes_process_locked	= g->p.mb_proc_locked	*1024L*1024L;
	g->p.bytes_thread		= g->p.mb_thread	*1024L*1024L;

	g->data = setup_shared_data(g->p.bytes_global);

	/* Startup serialization: */
	mutex_init_pshared(&g->start_work_mutex);
	cond_init_pshared(&g->start_work_cond);
	mutex_init_pshared(&g->startup_mutex);
	cond_init_pshared(&g->startup_cond);
	mutex_init_pshared(&g->stop_work_mutex);

	init_thread_data();

	tprintf("#\n");
	if (parse_setup_cpu_list() || parse_setup_node_list())
		return -1;
	tprintf("#\n");

	print_summary();

	return 0;
}

static void deinit(void)
{
	free_data(g->data, g->p.bytes_global);
	g->data = NULL;

	deinit_thread_data();

	free_data(g, sizeof(*g));
	g = NULL;
}

/*
 * Print a short or long result, depending on the verbosity setting:
 */
static void print_res(const char *name, double val,
		      const char *txt_unit, const char *txt_short, const char *txt_long)
{
	if (!name)
		name = "main,";

	if (!quiet)
		printf(" %-30s %15.3f, %-15s %s\n", name, val, txt_unit, txt_short);
	else
		printf(" %14.3f %s\n", val, txt_long);
}

static int __bench_numa(const char *name)
{
	struct timeval start, stop, diff;
	u64 runtime_ns_min, runtime_ns_sum;
	pid_t *pids, pid, wpid;
	double delta_runtime;
	double runtime_avg;
	double runtime_sec_max;
	double runtime_sec_min;
	int wait_stat;
	double bytes;
	int i, t, p;

	if (init())
		return -1;

	pids = zalloc(g->p.nr_proc * sizeof(*pids));
	pid = -1;

	if (g->p.serialize_startup) {
		tprintf(" #\n");
		tprintf(" # Startup synchronization: ..."); fflush(stdout);
	}

	gettimeofday(&start, NULL);

	for (i = 0; i < g->p.nr_proc; i++) {
		pid = fork();
		dprintf(" # process %2d: PID %d\n", i, pid);

		BUG_ON(pid < 0);
		if (!pid) {
			/* Child process: */
			worker_process(i);

			exit(0);
		}
		pids[i] = pid;

	}

	if (g->p.serialize_startup) {
		bool threads_ready = false;
		double startup_sec;

		/*
		 * Wait for all the threads to start up. The last thread will
		 * signal this process.
		 */
		mutex_lock(&g->startup_mutex);
		while (g->nr_tasks_started != g->p.nr_tasks)
			cond_wait(&g->startup_cond, &g->startup_mutex);

		mutex_unlock(&g->startup_mutex);

		/* Wait for all threads to be at the start_work_cond. */
		while (!threads_ready) {
			mutex_lock(&g->start_work_mutex);
			threads_ready = (g->nr_tasks_working == g->p.nr_tasks);
			mutex_unlock(&g->start_work_mutex);
			if (!threads_ready)
				usleep(1);
		}

		gettimeofday(&stop, NULL);

		timersub(&stop, &start, &diff);

		startup_sec = diff.tv_sec * NSEC_PER_SEC;
		startup_sec += diff.tv_usec * NSEC_PER_USEC;
		startup_sec /= NSEC_PER_SEC;

		tprintf(" threads initialized in %.6f seconds.\n", startup_sec);
		tprintf(" #\n");

		start = stop;
		/* Start all threads running. */
		mutex_lock(&g->start_work_mutex);
		g->start_work = true;
		mutex_unlock(&g->start_work_mutex);
		cond_broadcast(&g->start_work_cond);
	} else {
		gettimeofday(&start, NULL);
	}

	/* Parent process: */


	for (i = 0; i < g->p.nr_proc; i++) {
		wpid = waitpid(pids[i], &wait_stat, 0);
		BUG_ON(wpid < 0);
		BUG_ON(!WIFEXITED(wait_stat));

	}

	runtime_ns_sum = 0;
	runtime_ns_min = -1LL;

	for (t = 0; t < g->p.nr_tasks; t++) {
		u64 thread_runtime_ns = g->threads[t].runtime_ns;

		runtime_ns_sum += thread_runtime_ns;
		runtime_ns_min = min(thread_runtime_ns, runtime_ns_min);
	}

	gettimeofday(&stop, NULL);
	timersub(&stop, &start, &diff);

	BUG_ON(bench_format != BENCH_FORMAT_DEFAULT);

	tprintf("\n ###\n");
	tprintf("\n");

	runtime_sec_max = diff.tv_sec * NSEC_PER_SEC;
	runtime_sec_max += diff.tv_usec * NSEC_PER_USEC;
	runtime_sec_max /= NSEC_PER_SEC;

	runtime_sec_min = runtime_ns_min / NSEC_PER_SEC;

	bytes = g->bytes_done;
	runtime_avg = (double)runtime_ns_sum / g->p.nr_tasks / NSEC_PER_SEC;

	if (g->p.measure_convergence) {
		print_res(name, runtime_sec_max,
			"secs,", "NUMA-convergence-latency", "secs latency to NUMA-converge");
	}

	print_res(name, runtime_sec_max,
		"secs,", "runtime-max/thread",	"secs slowest (max) thread-runtime");

	print_res(name, runtime_sec_min,
		"secs,", "runtime-min/thread",	"secs fastest (min) thread-runtime");

	print_res(name, runtime_avg,
		"secs,", "runtime-avg/thread",	"secs average thread-runtime");

	delta_runtime = (runtime_sec_max - runtime_sec_min)/2.0;
	print_res(name, delta_runtime / runtime_sec_max * 100.0,
		"%,", "spread-runtime/thread",	"% difference between max/avg runtime");

	print_res(name, bytes / g->p.nr_tasks / 1e9,
		"GB,", "data/thread",		"GB data processed, per thread");

	print_res(name, bytes / 1e9,
		"GB,", "data-total",		"GB data processed, total");

	print_res(name, runtime_sec_max * NSEC_PER_SEC / (bytes / g->p.nr_tasks),
		"nsecs,", "runtime/byte/thread","nsecs/byte/thread runtime");

	print_res(name, bytes / g->p.nr_tasks / 1e9 / runtime_sec_max,
		"GB/sec,", "thread-speed",	"GB/sec/thread speed");

	print_res(name, bytes / runtime_sec_max / 1e9,
		"GB/sec,", "total-speed",	"GB/sec total speed");

	if (g->p.show_details >= 2) {
		char tname[14 + 2 * 11 + 1];
		struct thread_data *td;
		for (p = 0; p < g->p.nr_proc; p++) {
			for (t = 0; t < g->p.nr_threads; t++) {
				memset(tname, 0, sizeof(tname));
				td = g->threads + p*g->p.nr_threads + t;
				snprintf(tname, sizeof(tname), "process%d:thread%d", p, t);
				print_res(tname, td->speed_gbs,
					"GB/sec",	"thread-speed", "GB/sec/thread speed");
				print_res(tname, td->system_time_ns / NSEC_PER_SEC,
					"secs",	"thread-system-time", "system CPU time/thread");
				print_res(tname, td->user_time_ns / NSEC_PER_SEC,
					"secs",	"thread-user-time", "user CPU time/thread");
			}
		}
	}

	free(pids);

	deinit();

	return 0;
}

#define MAX_ARGS 50

static int command_size(const char **argv)
{
	int size = 0;

	while (*argv) {
		size++;
		argv++;
	}

	BUG_ON(size >= MAX_ARGS);

	return size;
}

static void init_params(struct params *p, const char *name, int argc, const char **argv)
{
	int i;

	printf("\n # Running %s \"perf bench numa", name);

	for (i = 0; i < argc; i++)
		printf(" %s", argv[i]);

	printf("\"\n");

	memset(p, 0, sizeof(*p));

	/* Initialize nonzero defaults: */

	p->serialize_startup		= 1;
	p->data_reads			= true;
	p->data_writes			= true;
	p->data_backwards		= true;
	p->data_rand_walk		= true;
	p->nr_loops			= -1;
	p->init_random			= true;
	p->mb_global_str		= "1";
	p->nr_proc			= 1;
	p->nr_threads			= 1;
	p->nr_secs			= 5;
	p->run_all			= argc == 1;
}

static int run_bench_numa(const char *name, const char **argv)
{
	int argc = command_size(argv);

	init_params(&p0, name, argc, argv);
	argc = parse_options(argc, argv, options, bench_numa_usage, 0);
	if (argc)
		goto err;

	if (__bench_numa(name))
		goto err;

	return 0;

err:
	return -1;
}

#define OPT_BW_RAM		"-s",  "20", "-zZq",    "--thp", " 1", "--no-data_rand_walk"
#define OPT_BW_RAM_NOTHP	OPT_BW_RAM,		"--thp", "-1"

#define OPT_CONV		"-s", "100", "-zZ0qcm", "--thp", " 1"
#define OPT_CONV_NOTHP		OPT_CONV,		"--thp", "-1"

#define OPT_BW			"-s",  "20", "-zZ0q",   "--thp", " 1"
#define OPT_BW_NOTHP		OPT_BW,			"--thp", "-1"

/*
 * The built-in test-suite executed by "perf bench numa -a".
 *
 * (A minimum of 4 nodes and 16 GB of RAM is recommended.)
 */
static const char *tests[][MAX_ARGS] = {
   /* Basic single-stream NUMA bandwidth measurements: */
   { "RAM-bw-local,",     "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
			  "-C" ,   "0", "-M",   "0", OPT_BW_RAM },
   { "RAM-bw-local-NOTHP,",
			  "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
			  "-C" ,   "0", "-M",   "0", OPT_BW_RAM_NOTHP },
   { "RAM-bw-remote,",    "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
			  "-C" ,   "0", "-M",   "1", OPT_BW_RAM },

   /* 2-stream NUMA bandwidth measurements: */
   { "RAM-bw-local-2x,",  "mem",  "-p",  "2",  "-t",  "1", "-P", "1024",
			   "-C", "0,2", "-M", "0x2", OPT_BW_RAM },
   { "RAM-bw-remote-2x,", "mem",  "-p",  "2",  "-t",  "1", "-P", "1024",
		 	   "-C", "0,2", "-M", "1x2", OPT_BW_RAM },

   /* Cross-stream NUMA bandwidth measurement: */
   { "RAM-bw-cross,",     "mem",  "-p",  "2",  "-t",  "1", "-P", "1024",
		 	   "-C", "0,8", "-M", "1,0", OPT_BW_RAM },

   /* Convergence latency measurements: */
   { " 1x3-convergence,", "mem",  "-p",  "1", "-t",  "3", "-P",  "512", OPT_CONV },
   { " 1x4-convergence,", "mem",  "-p",  "1", "-t",  "4", "-P",  "512", OPT_CONV },
   { " 1x6-convergence,", "mem",  "-p",  "1", "-t",  "6", "-P", "1020", OPT_CONV },
   { " 2x3-convergence,", "mem",  "-p",  "2", "-t",  "3", "-P", "1020", OPT_CONV },
   { " 3x3-convergence,", "mem",  "-p",  "3", "-t",  "3", "-P", "1020", OPT_CONV },
   { " 4x4-convergence,", "mem",  "-p",  "4", "-t",  "4", "-P",  "512", OPT_CONV },
   { " 4x4-convergence-NOTHP,",
			  "mem",  "-p",  "4", "-t",  "4", "-P",  "512", OPT_CONV_NOTHP },
   { " 4x6-convergence,", "mem",  "-p",  "4", "-t",  "6", "-P", "1020", OPT_CONV },
   { " 4x8-convergence,", "mem",  "-p",  "4", "-t",  "8", "-P",  "512", OPT_CONV },
   { " 8x4-convergence,", "mem",  "-p",  "8", "-t",  "4", "-P",  "512", OPT_CONV },
   { " 8x4-convergence-NOTHP,",
			  "mem",  "-p",  "8", "-t",  "4", "-P",  "512", OPT_CONV_NOTHP },
   { " 3x1-convergence,", "mem",  "-p",  "3", "-t",  "1", "-P",  "512", OPT_CONV },
   { " 4x1-convergence,", "mem",  "-p",  "4", "-t",  "1", "-P",  "512", OPT_CONV },
   { " 8x1-convergence,", "mem",  "-p",  "8", "-t",  "1", "-P",  "512", OPT_CONV },
   { "16x1-convergence,", "mem",  "-p", "16", "-t",  "1", "-P",  "256", OPT_CONV },
   { "32x1-convergence,", "mem",  "-p", "32", "-t",  "1", "-P",  "128", OPT_CONV },

   /* Various NUMA process/thread layout bandwidth measurements: */
   { " 2x1-bw-process,",  "mem",  "-p",  "2", "-t",  "1", "-P", "1024", OPT_BW },
   { " 3x1-bw-process,",  "mem",  "-p",  "3", "-t",  "1", "-P", "1024", OPT_BW },
   { " 4x1-bw-process,",  "mem",  "-p",  "4", "-t",  "1", "-P", "1024", OPT_BW },
   { " 8x1-bw-process,",  "mem",  "-p",  "8", "-t",  "1", "-P", " 512", OPT_BW },
   { " 8x1-bw-process-NOTHP,",
			  "mem",  "-p",  "8", "-t",  "1", "-P", " 512", OPT_BW_NOTHP },
   { "16x1-bw-process,",  "mem",  "-p", "16", "-t",  "1", "-P",  "256", OPT_BW },

   { " 1x4-bw-thread,",   "mem",  "-p",  "1", "-t",  "4", "-T",  "256", OPT_BW },
   { " 1x8-bw-thread,",   "mem",  "-p",  "1", "-t",  "8", "-T",  "256", OPT_BW },
   { "1x16-bw-thread,",   "mem",  "-p",  "1", "-t", "16", "-T",  "128", OPT_BW },
   { "1x32-bw-thread,",   "mem",  "-p",  "1", "-t", "32", "-T",   "64", OPT_BW },

   { " 2x3-bw-process,",  "mem",  "-p",  "2", "-t",  "3", "-P",  "512", OPT_BW },
   { " 4x4-bw-process,",  "mem",  "-p",  "4", "-t",  "4", "-P",  "512", OPT_BW },
   { " 4x6-bw-process,",  "mem",  "-p",  "4", "-t",  "6", "-P",  "512", OPT_BW },
   { " 4x8-bw-process,",  "mem",  "-p",  "4", "-t",  "8", "-P",  "512", OPT_BW },
   { " 4x8-bw-process-NOTHP,",
			  "mem",  "-p",  "4", "-t",  "8", "-P",  "512", OPT_BW_NOTHP },
   { " 3x3-bw-process,",  "mem",  "-p",  "3", "-t",  "3", "-P",  "512", OPT_BW },
   { " 5x5-bw-process,",  "mem",  "-p",  "5", "-t",  "5", "-P",  "512", OPT_BW },

   { "2x16-bw-process,",  "mem",  "-p",  "2", "-t", "16", "-P",  "512", OPT_BW },
   { "1x32-bw-process,",  "mem",  "-p",  "1", "-t", "32", "-P", "2048", OPT_BW },

   { "numa02-bw,",        "mem",  "-p",  "1", "-t", "32", "-T",   "32", OPT_BW },
   { "numa02-bw-NOTHP,",  "mem",  "-p",  "1", "-t", "32", "-T",   "32", OPT_BW_NOTHP },
   { "numa01-bw-thread,", "mem",  "-p",  "2", "-t", "16", "-T",  "192", OPT_BW },
   { "numa01-bw-thread-NOTHP,",
			  "mem",  "-p",  "2", "-t", "16", "-T",  "192", OPT_BW_NOTHP },
};

static int bench_all(void)
{
	int nr = ARRAY_SIZE(tests);
	int ret;
	int i;

	ret = system("echo ' #'; echo ' # Running test on: '$(uname -a); echo ' #'");
	BUG_ON(ret < 0);

	for (i = 0; i < nr; i++) {
		run_bench_numa(tests[i][0], tests[i] + 1);
	}

	printf("\n");

	return 0;
}

int bench_numa(int argc, const char **argv)
{
	init_params(&p0, "main,", argc, argv);
	argc = parse_options(argc, argv, options, bench_numa_usage, 0);
	if (argc)
		goto err;

	if (p0.run_all)
		return bench_all();

	if (__bench_numa(NULL))
		goto err;

	return 0;

err:
	usage_with_options(numa_usage, options);
	return -1;
}
