// File: sidscrazy[P]Paxos/./paxos_controller.cpp
// Function: PaxosController::PaxosController(int, int)
PaxosController (int n, int p){
		nodes = n;
		proposers = p;
		children = std::vector<int> (n);
		sockets = std::vector<int> (n);
		threads = std::vector<std::thread> (n);
		mutexes = std::vector<std::mutex> (n);
		log = new PaxosNodeLogger (CONTROLLER_LOG);



		for (int i = 0; i < nodes; i++){
			
			int *s = (int *) malloc (2 * sizeof (int));
			
			if (s == NULL){
				exit (1);
			}

			if (socketpair(AF_UNIX, SOCK_DGRAM, 0, s) < 0){
				exit (1);
			}

			sockets[i] = s[0];

			int pid = fork ();
			if (pid == 0 ){
				close (s[0]);
				dup2 (s[1], 0);
				dup2 (s[1], 1);
				char *args[2];
				args[0] = (char *)malloc (7);
				if (args[0] == NULL){
					exit (1);
				}
				memcpy (args[0], "./node", 6);
				args[0][7] = '\0';
				args[1] = NULL;
				execvp (args[0], args);
			} else {
				children[i] = pid;
				close (s[1]);
			}

			int role = ACCEPTOR;
			if (i < proposers){
				role |= PROPOSER;
				role |= LEARNER;
			}
			message init_message (i, role, nodes, -1, MSG_INIT);
			mutexes[i].lock ();
			send_packet (sockets[i], &init_message);
			mutexes[i].unlock ();
			free (s);
			threads[i] = std::thread ( [this, i] { this->network_simulator(i); } );
		}

	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x118(%rbp)
movq %rdi, %rax
movq %rax, -0x138(%rbp)
callq 0x3c80
movq -0x118(%rbp), %rdi
addq $0x18, %rdi
movq %rdi, -0x130(%rbp)
callq 0x3c80
movq -0x118(%rbp), %rdi
addq $0x30, %rdi
movq %rdi, -0x128(%rbp)
callq 0x3ca0
movq -0x118(%rbp), %rdi
addq $0x48, %rdi
movq %rdi, -0x120(%rbp)
callq 0x3cc0
movq -0x118(%rbp), %rdi
addq $0x60, %rdi
callq 0x3ce0
movq -0x118(%rbp), %rdi
addq $0x88, %rdi
callq 0x3ce0
movq -0x118(%rbp), %rax
movb $0x0, 0xb8(%rax)
movl -0xc(%rbp), %ecx
movl %ecx, 0xb0(%rax)
movl -0x10(%rbp), %ecx
movl %ecx, 0xb4(%rax)
movslq -0xc(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq -0x29(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x3d00
movq -0x110(%rbp), %rsi
movq -0x108(%rbp), %rdx
leaq -0x28(%rbp), %rdi
callq 0x3d20
jmp 0x310b
movq -0x138(%rbp), %rdi
leaq -0x28(%rbp), %rsi
movq %rsi, -0x150(%rbp)
callq 0x3d90
movq -0x150(%rbp), %rdi
callq 0x3dc0
leaq -0x29(%rbp), %rdi
callq 0x3e20
movslq -0xc(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x59(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x3d00
movq -0x148(%rbp), %rsi
movq -0x140(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0x3d20
jmp 0x316b
movq -0x138(%rbp), %rdi
addq $0x18, %rdi
leaq -0x58(%rbp), %rsi
movq %rsi, -0x168(%rbp)
callq 0x3d90
movq -0x168(%rbp), %rdi
callq 0x3dc0
leaq -0x59(%rbp), %rdi
callq 0x3e20
movslq -0xc(%rbp), %rax
movq %rax, -0x160(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0x158(%rbp)
callq 0x3e40
movq -0x160(%rbp), %rsi
movq -0x158(%rbp), %rdx
leaq -0x78(%rbp), %rdi
callq 0x3e60
jmp 0x31cf
movq -0x138(%rbp), %rdi
addq $0x30, %rdi
leaq -0x78(%rbp), %rsi
movq %rsi, -0x180(%rbp)
callq 0x3ed0
movq -0x180(%rbp), %rdi
callq 0x3f00
leaq -0x79(%rbp), %rdi
callq 0x3f60
movslq -0xc(%rbp), %rax
movq %rax, -0x178(%rbp)
leaq -0x99(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0x3f80
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
leaq -0x98(%rbp), %rdi
callq 0x3fa0
jmp 0x3239
movq -0x138(%rbp), %rdi
addq $0x48, %rdi
leaq -0x98(%rbp), %rsi
movq %rsi, -0x190(%rbp)
callq 0x4010
movq -0x190(%rbp), %rdi
callq 0x4040
leaq -0x99(%rbp), %rdi
callq 0x40a0
movl $0x228, %edi            # imm = 0x228
callq 0x2230
movq %rax, -0x188(%rbp)
jmp 0x3282
movq -0x188(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x79e0
jmp 0x3295
movq -0x138(%rbp), %rax
movq -0x188(%rbp), %rcx
movq %rcx, 0xc0(%rax)
movl $0x0, -0xa0(%rbp)
movq -0x138(%rbp), %rcx
movl -0xa0(%rbp), %eax
cmpl 0xb0(%rcx), %eax
jge 0x362c
movl $0x8, %edi
callq 0x22a0
movq %rax, -0xa8(%rbp)
cmpq $0x0, -0xa8(%rbp)
jne 0x338f
movl $0x1, %edi
callq 0x2270
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x29(%rbp), %rdi
callq 0x3e20
jmp 0x3635
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x59(%rbp), %rdi
callq 0x3e20
jmp 0x3635
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x79(%rbp), %rdi
callq 0x3f60
jmp 0x3635
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x99(%rbp), %rdi
callq 0x40a0
jmp 0x3635
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x3635
movq -0x188(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
callq 0x2210
jmp 0x3635
movq -0xa8(%rbp), %rcx
movl $0x1, %edi
movl $0x2, %esi
xorl %edx, %edx
callq 0x21c0
cmpl $0x0, %eax
jge 0x33b6
movl $0x1, %edi
callq 0x2270
movq -0x138(%rbp), %rdi
movq -0xa8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x194(%rbp)
addq $0x18, %rdi
movslq -0xa0(%rbp), %rsi
callq 0x40c0
movl -0x194(%rbp), %ecx
movl %ecx, (%rax)
callq 0x2060
movl %eax, -0xac(%rbp)
cmpl $0x0, -0xac(%rbp)
jne 0x349b
movq -0xa8(%rbp), %rax
movl (%rax), %edi
callq 0x23f0
jmp 0x340c
movq -0xa8(%rbp), %rax
movl 0x4(%rax), %edi
xorl %esi, %esi
callq 0x2200
movq -0xa8(%rbp), %rax
movl 0x4(%rax), %edi
movl $0x1, %esi
callq 0x2200
movl $0x7, %edi
callq 0x22a0
movq %rax, -0xc0(%rbp)
cmpq $0x0, -0xc0(%rbp)
jne 0x3456
movl $0x1, %edi
callq 0x2270
movq -0xc0(%rbp), %rax
movl 0x5c4e(%rip), %ecx      # 0x90b1
movl %ecx, (%rax)
movw 0x5c49(%rip), %cx       # 0x90b5
movw %cx, 0x4(%rax)
movq -0xc0(%rbp), %rax
movb $0x0, 0x7(%rax)
movq $0x0, -0xb8(%rbp)
movq -0xc0(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x2190
jmp 0x34d5
movq -0x138(%rbp), %rdi
movl -0xac(%rbp), %eax
movl %eax, -0x198(%rbp)
movslq -0xa0(%rbp), %rsi
callq 0x40c0
movl -0x198(%rbp), %ecx
movl %ecx, (%rax)
movq -0xa8(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x23f0
jmp 0x34d3
jmp 0x34d5
movq -0x138(%rbp), %rcx
movl $0x4, -0xc4(%rbp)
movl -0xa0(%rbp), %eax
cmpl 0xb4(%rcx), %eax
jge 0x3512
movl -0xc4(%rbp), %eax
orl $0x1, %eax
movl %eax, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
orl $0x2, %eax
movl %eax, -0xc4(%rbp)
movq -0x138(%rbp), %rax
movl -0xa0(%rbp), %esi
movl -0xc4(%rbp), %edx
movl 0xb0(%rax), %ecx
leaq -0xe8(%rbp), %rdi
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
xorl %r9d, %r9d
callq 0x40e0
jmp 0x3542
movq -0x138(%rbp), %rdi
addq $0x48, %rdi
movslq -0xa0(%rbp), %rsi
callq 0x4120
movq %rax, %rdi
callq 0x4140
jmp 0x3563
movq -0x138(%rbp), %rdi
addq $0x18, %rdi
movslq -0xa0(%rbp), %rsi
callq 0x40c0
movl (%rax), %edi
leaq -0xe8(%rbp), %rsi
callq 0x2620
jmp 0x358a
movq -0x138(%rbp), %rdi
addq $0x48, %rdi
movslq -0xa0(%rbp), %rsi
callq 0x4120
movq %rax, %rdi
callq 0x4170
jmp 0x35ab
movq -0xa8(%rbp), %rdi
callq 0x2260
movq -0x138(%rbp), %rax
movq %rax, -0x100(%rbp)
movl -0xa0(%rbp), %eax
movl %eax, -0xf8(%rbp)
leaq -0xf0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x4190
jmp 0x35e6
movq -0x138(%rbp), %rdi
addq $0x30, %rdi
movslq -0xa0(%rbp), %rsi
callq 0x4240
movq %rax, %rdi
leaq -0xf0(%rbp), %rsi
callq 0x4260
leaq -0xf0(%rbp), %rdi
callq 0x42a0
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
jmp 0x32b4
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
movq -0x120(%rbp), %rdi
callq 0x4040
movq -0x128(%rbp), %rdi
callq 0x3f00
movq -0x130(%rbp), %rdi
callq 0x3dc0
movq -0x118(%rbp), %rdi
callq 0x3dc0
movq -0x38(%rbp), %rdi
callq 0x2390
nop