// File: /workspace/github_c_makefile_star2_O0/antonblanchard[P]will-it-scale/main.c
// Function: main
int main(int argc, char *argv[])
{
	int opt_tasks = 1;
	int opt_iterations = 0;
	int iterations = 0;
	int i, n;
	char *m;
	static unsigned long long *results[MAX_TASKS];
	hwloc_topology_t topology;
	unsigned long long prev[MAX_TASKS] = {0, };
	unsigned long long total = 0;
	int fd[2];
	bool smt_affinity = false;
	struct args *args;
	bool verbose = false;

	while (1) {
		signed char c = getopt(argc, argv, "mt:s:hvn");
		if (c < 0)
			break;

		switch (c) {
			case 'm':
				smt_affinity = true;
				break;

			case 't':
				opt_tasks = atoi(optarg);
				if (opt_tasks > MAX_TASKS) {
					printf("tasks cannot exceed %d\n",
					       MAX_TASKS);
					exit(1);
				}
				break;

			case 's':
				opt_iterations = atoi(optarg);
				break;

			case 'v':
				verbose = true;
				break;

			case 'n':
				use_affinity = false;
				break;

			default:
				usage(argv[0]);
		}
	}

	if (optind < argc)
		usage(argv[0]);

	if (smt_affinity && (use_affinity == false))
		usage(argv[0]);

	m = initialise_shared_area(opt_tasks * MAX_CACHELINE_SIZE);
	for (i = 0; i < opt_tasks; i++)
		results[i] = (unsigned long long *)&m[i * MAX_CACHELINE_SIZE];

	if (pipe(fd) == -1) {
		perror("pipe");
		exit(1);
	}

	testcase_prepare(opt_tasks);

	hwloc_topology_init(&topology);
	hwloc_topology_load(topology);

	n = hwloc_get_nbobjs_by_type(topology,
			smt_affinity ? HWLOC_OBJ_PU : HWLOC_OBJ_CORE);
	if (n == 0) {
		printf("No Cores/PUs found. Try %s -m flag\n",
		       smt_affinity ? "removing" : "adding");
		exit(1);
	}
	if (n < 1) {
		perror("hwloc_get_nbobjs_by_type");
		exit(1);
	}

	args = malloc(opt_tasks * sizeof(struct args));
	if (!args) {
		perror("malloc");
		exit(1);
	}

	for (i = 0; i < opt_tasks; i++) {
		hwloc_obj_t obj;
		hwloc_cpuset_t old_cpuset;
		int flags = 0;

		args[i].func = testcase;
		args[i].arg1 = results[i];
		args[i].arg2 = i;
		args[i].poll_fd = fd[0];

		obj = hwloc_get_obj_by_type(topology,
				smt_affinity ? HWLOC_OBJ_PU : HWLOC_OBJ_CORE,
				i % n);

		if (hwloc_topology_dup(&args[i].topology, topology)) {
			perror("hwloc_topology_dup");
			exit(1);
		}

		if (!(args[i].cpuset = hwloc_bitmap_dup(obj->cpuset))) {
			perror("hwloc_bitmap_dup");
			exit(1);
		}

		old_cpuset = hwloc_bitmap_alloc();
		if (!old_cpuset) {
			perror("hwloc_bitmap_alloc");
			exit(1);
		}
#ifdef THREADS
		flags |= HWLOC_CPUBIND_THREAD;
#endif
		if (hwloc_get_cpubind(topology, old_cpuset, flags) < 0) {
			perror("hwloc_get_cpubind");
			exit(1);
		}

		if (use_affinity && hwloc_set_cpubind(topology, obj->cpuset, flags) < 0) {
			perror("hwloc_set_cpubind");
			exit(1);
		}

		new_task_affinity(&args[i]);

		if (use_affinity && hwloc_set_cpubind(topology, old_cpuset, flags) < 0) {
			perror("hwloc_set_cpubind");
			exit(1);
		}

		hwloc_bitmap_free(old_cpuset);
	}

	if (write(fd[1], &i, 1) != 1) {
		perror("write");
		exit(1);
	}

	hwloc_topology_destroy(topology);

	printf("testcase:%s\n", testcase_description);

	printf("warmup\n");

	while (1) {
		unsigned long long sum = 0, min = -1ULL, max = 0;

		sleep(1);

		for (i = 0; i < opt_tasks; i++) {
			unsigned long long val = *(results[i]);
			unsigned long long diff = val - prev[i];

			if (verbose)
				printf("%4d -> %llu\n", i, diff);

			if (diff < min)
				min = diff;

			if (diff > max)
				max = diff;

			sum += diff;
			prev[i] = val;
		}

		printf("min:%llu max:%llu total:%llu\n", min, max, sum);

		if (iterations == WARMUP_ITERATIONS)
			printf("measurement\n");

		if (iterations++ > WARMUP_ITERATIONS)
			total += sum;

		if (opt_iterations &&
		    (iterations > (opt_iterations + WARMUP_ITERATIONS))) {
			printf("average:%llu\n", total / opt_iterations);
			break;
		}
	}

	kill_tasks();

	for (i = 0; i < opt_tasks; i++) {
		hwloc_bitmap_free(args[i].cpuset);
		hwloc_topology_destroy(args[i].topology);
	}
	free(args);

	testcase_cleanup();
	exit(0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40b0, %rsp           # imm = 0x40B0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x1, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
leaq -0x4040(%rbp), %rdi
xorl %esi, %esi
movl $0x4000, %edx           # imm = 0x4000
callq 0x2120
movq $0x0, -0x4048(%rbp)
movb $0x0, -0x4051(%rbp)
movb $0x0, -0x4061(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x1aa4(%rip), %rdx      # 0x402c
callq 0x2220
movb %al, -0x4062(%rbp)
movsbl -0x4062(%rbp), %eax
cmpl $0x0, %eax
jge 0x25a4
jmp 0x2651
movsbl -0x4062(%rbp), %eax
addl $-0x6d, %eax
movl %eax, %ecx
movq %rcx, -0x40b0(%rbp)
subl $0x9, %eax
ja 0x2640
movq -0x40b0(%rbp), %rax
leaq 0x1a36(%rip), %rcx      # 0x4004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, -0x4051(%rbp)
jmp 0x264c
movq 0x39f9(%rip), %rax      # 0x5fe0
movq (%rax), %rdi
callq 0x2250
movl %eax, -0x14(%rbp)
cmpl $0x800, -0x14(%rbp)     # imm = 0x800
jle 0x2618
leaq 0x1a33(%rip), %rdi      # 0x4035
movl $0x800, %esi            # imm = 0x800
movb $0x0, %al
callq 0x20e0
movl $0x1, %edi
callq 0x2290
jmp 0x264c
movq 0x39bf(%rip), %rax      # 0x5fe0
movq (%rax), %rdi
callq 0x2250
movl %eax, -0x18(%rbp)
jmp 0x264c
movb $0x1, -0x4061(%rbp)
jmp 0x264c
movb $0x0, 0x3b42(%rip)      # 0x6180
jmp 0x264c
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x2c90
jmp 0x257a
movq 0x3980(%rip), %rax      # 0x5fd8
movl (%rax), %eax
cmpl -0x8(%rbp), %eax
jge 0x266b
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x2c90
testb $0x1, -0x4051(%rbp)
je 0x2690
movb 0x3b06(%rip), %al       # 0x6180
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x2690
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x2c90
movl -0x14(%rbp), %eax
shll $0x8, %eax
movslq %eax, %rdi
callq 0x2cf0
movq %rax, -0x30(%rbp)
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x26da
movq -0x30(%rbp), %rdx
movl -0x20(%rbp), %eax
shll $0x8, %eax
cltq
addq %rax, %rdx
movslq -0x20(%rbp), %rcx
leaq 0xbb15(%rip), %rax      # 0xe1e0
movq %rdx, (%rax,%rcx,8)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x26a9
leaq -0x4050(%rbp), %rdi
callq 0x2140
cmpl $-0x1, %eax
jne 0x2701
leaq 0x195b(%rip), %rdi      # 0x404d
callq 0x2210
movl $0x1, %edi
callq 0x2290
movslq -0x14(%rbp), %rdi
callq 0x2fd0
leaq -0x38(%rbp), %rdi
callq 0x2090
movq -0x38(%rbp), %rdi
callq 0x20a0
movq -0x38(%rbp), %rdi
movb -0x4051(%rbp), %cl
movl $0x2, %esi
movl $0x3, %eax
testb $0x1, %cl
cmovnel %eax, %esi
callq 0x2e10
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x2777
movb -0x4051(%rbp), %cl
leaq 0x192e(%rip), %rsi      # 0x407f
leaq 0x191e(%rip), %rax      # 0x4076
testb $0x1, %cl
cmovneq %rax, %rsi
leaq 0x18ec(%rip), %rdi      # 0x4052
movb $0x0, %al
callq 0x20e0
movl $0x1, %edi
callq 0x2290
cmpl $0x1, -0x24(%rbp)
jge 0x2793
leaq 0x1902(%rip), %rdi      # 0x4086
callq 0x2210
movl $0x1, %edi
callq 0x2290
movslq -0x14(%rbp), %rax
imulq $0x30, %rax, %rdi
callq 0x21a0
movq %rax, -0x4060(%rbp)
cmpq $0x0, -0x4060(%rbp)
jne 0x27c7
leaq 0x18e7(%rip), %rdi      # 0x409f
callq 0x2210
movl $0x1, %edi
callq 0x2290
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2a1e
movl $0x0, -0x407c(%rbp)
movq -0x4060(%rbp), %rax
movslq -0x20(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
leaq 0x893(%rip), %rcx       # 0x3090
movq %rcx, (%rax)
movslq -0x20(%rbp), %rcx
leaq 0xb9d5(%rip), %rax      # 0xe1e0
movq (%rax,%rcx,8), %rcx
movq -0x4060(%rbp), %rax
movslq -0x20(%rbp), %rdx
imulq $0x30, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movslq -0x20(%rbp), %rcx
movq -0x4060(%rbp), %rax
movslq -0x20(%rbp), %rdx
imulq $0x30, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movl -0x4050(%rbp), %ecx
movq -0x4060(%rbp), %rax
movslq -0x20(%rbp), %rdx
imulq $0x30, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x18(%rax)
movq -0x38(%rbp), %rdi
movb -0x4051(%rbp), %cl
movl $0x2, %esi
movl $0x3, %eax
testb $0x1, %cl
cmovnel %eax, %esi
movl -0x20(%rbp), %eax
cltd
idivl -0x24(%rbp)
callq 0x2e70
movq %rax, -0x4070(%rbp)
movq -0x4060(%rbp), %rdi
movslq -0x20(%rbp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
addq $0x20, %rdi
movq -0x38(%rbp), %rsi
callq 0x21b0
cmpl $0x0, %eax
je 0x28c1
leaq 0x17f4(%rip), %rdi      # 0x40a6
callq 0x2210
movl $0x1, %edi
callq 0x2290
movq -0x4070(%rbp), %rax
movq 0xb8(%rax), %rdi
callq 0x2160
movq -0x4060(%rbp), %rcx
movslq -0x20(%rbp), %rdx
imulq $0x30, %rdx, %rdx
addq %rdx, %rcx
movq %rax, 0x28(%rcx)
cmpq $0x0, %rax
jne 0x2906
leaq 0x17c2(%rip), %rdi      # 0x40b9
callq 0x2210
movl $0x1, %edi
callq 0x2290
callq 0x2030
movq %rax, -0x4078(%rbp)
cmpq $0x0, -0x4078(%rbp)
jne 0x2932
leaq 0x17a7(%rip), %rdi      # 0x40ca
callq 0x2210
movl $0x1, %edi
callq 0x2290
movl -0x407c(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x407c(%rbp)
movq -0x38(%rbp), %rdi
movq -0x4078(%rbp), %rsi
movl -0x407c(%rbp), %edx
callq 0x2170
cmpl $0x0, %eax
jge 0x2972
leaq 0x177a(%rip), %rdi      # 0x40dd
callq 0x2210
movl $0x1, %edi
callq 0x2290
testb $0x1, 0x3807(%rip)      # 0x6180
je 0x29b3
movq -0x38(%rbp), %rdi
movq -0x4070(%rbp), %rax
movq 0xb8(%rax), %rsi
movl -0x407c(%rbp), %edx
callq 0x2180
cmpl $0x0, %eax
jge 0x29b3
leaq 0x174b(%rip), %rdi      # 0x40ef
callq 0x2210
movl $0x1, %edi
callq 0x2290
movq -0x4060(%rbp), %rdi
movslq -0x20(%rbp), %rax
imulq $0x30, %rax, %rax
addq %rax, %rdi
callq 0x2440
testb $0x1, 0x37af(%rip)      # 0x6180
je 0x2a04
movq -0x38(%rbp), %rdi
movq -0x4078(%rbp), %rsi
movl -0x407c(%rbp), %edx
callq 0x2180
cmpl $0x0, %eax
jge 0x2a04
leaq 0x16fa(%rip), %rdi      # 0x40ef
callq 0x2210
movl $0x1, %edi
callq 0x2290
movq -0x4078(%rbp), %rdi
callq 0x2060
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x27ce
movl -0x404c(%rbp), %edi
leaq -0x20(%rbp), %rsi
movl $0x1, %edx
callq 0x20c0
cmpq $0x1, %rax
je 0x2a4e
leaq 0x16c2(%rip), %rdi      # 0x4101
callq 0x2210
movl $0x1, %edi
callq 0x2290
movq -0x38(%rbp), %rdi
callq 0x2270
leaq 0x3732(%rip), %rax      # 0x6190
movq (%rax), %rsi
leaq 0x169f(%rip), %rdi      # 0x4107
movb $0x0, %al
callq 0x20e0
leaq 0x169e(%rip), %rdi      # 0x4114
movb $0x0, %al
callq 0x20e0
movq $0x0, -0x4088(%rbp)
movq $-0x1, -0x4090(%rbp)
movq $0x0, -0x4098(%rbp)
movl $0x1, %edi
callq 0x22c0
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2b81
movslq -0x20(%rbp), %rcx
leaq 0xb71a(%rip), %rax      # 0xe1e0
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movq %rax, -0x40a0(%rbp)
movq -0x40a0(%rbp), %rax
movslq -0x20(%rbp), %rcx
subq -0x4040(%rbp,%rcx,8), %rax
movq %rax, -0x40a8(%rbp)
testb $0x1, -0x4061(%rbp)
je 0x2b0f
movl -0x20(%rbp), %esi
movq -0x40a8(%rbp), %rdx
leaq 0x1614(%rip), %rdi      # 0x411c
movb $0x0, %al
callq 0x20e0
movq -0x40a8(%rbp), %rax
cmpq -0x4090(%rbp), %rax
jae 0x2b2d
movq -0x40a8(%rbp), %rax
movq %rax, -0x4090(%rbp)
movq -0x40a8(%rbp), %rax
cmpq -0x4098(%rbp), %rax
jbe 0x2b4b
movq -0x40a8(%rbp), %rax
movq %rax, -0x4098(%rbp)
movq -0x40a8(%rbp), %rax
addq -0x4088(%rbp), %rax
movq %rax, -0x4088(%rbp)
movq -0x40a0(%rbp), %rcx
movslq -0x20(%rbp), %rax
movq %rcx, -0x4040(%rbp,%rax,8)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x2aaf
movq -0x4090(%rbp), %rsi
movq -0x4098(%rbp), %rdx
movq -0x4088(%rbp), %rcx
leaq 0x158c(%rip), %rdi      # 0x4129
movb $0x0, %al
callq 0x20e0
cmpl $0x5, -0x1c(%rbp)
jne 0x2bb8
leaq 0x1596(%rip), %rdi      # 0x4147
movb $0x0, %al
callq 0x20e0
movl -0x1c(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x1c(%rbp)
cmpl $0x5, %eax
jle 0x2bdd
movq -0x4088(%rbp), %rax
addq -0x4048(%rbp), %rax
movq %rax, -0x4048(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0x2c13
movl -0x1c(%rbp), %eax
movl -0x18(%rbp), %ecx
addl $0x5, %ecx
cmpl %ecx, %eax
jle 0x2c13
movq -0x4048(%rbp), %rax
movslq -0x18(%rbp), %rcx
xorl %edx, %edx
divq %rcx
movq %rax, %rsi
leaq 0x154a(%rip), %rdi      # 0x4154
movb $0x0, %al
callq 0x20e0
jmp 0x2c18
jmp 0x2a7d
callq 0x2ed0
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2c6d
movq -0x4060(%rbp), %rax
movslq -0x20(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x28(%rax), %rdi
callq 0x2060
movq -0x4060(%rbp), %rax
movslq -0x20(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x20(%rax), %rdi
callq 0x2270
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x2c24
movq -0x4060(%rbp), %rdi
callq 0x2050
callq 0x3140
xorl %edi, %edi
callq 0x2290
nopw %cs:(%rax,%rax)