// File: /workspace/github_c_makefile_star2_O2/unixlab[P]cloudflare-udp-ping/udpserver.c
// Function: main
int main(int argc, const char *argv[])
{
	const char *listen_addr_str = "0.0.0.0:4321";
	int thread_num = 1;
	int reuseport = 0;
	int polling = 0;
	int busy_poll = 0;

	static struct option long_options[] = {
		{"busy-poll", required_argument, 0, 'b'},
		{"threads", required_argument, 0, 't'},
		{"polling", no_argument, 0, 'p'},
		{"reuseport", no_argument, 0, 'r'},
		{"listen", required_argument, 0, 'l'},
		{NULL, 0, 0, 0}};
	const char *optstring = optstring_from_long_options(long_options);

	optind = 1;
	while (1) {
		int option_index = 0;
		int arg = getopt_long(argc, (char **)argv, optstring,
				      long_options, &option_index);
		if (arg == -1) {
			break;
		}

		switch (arg) {
		case 'b':
			busy_poll = atoi(optarg);
			break;

		case 't':
			thread_num = atoi(optarg);
			break;

		case 'p':
			polling = 1;
			break;

		case 'r':
			reuseport = 1;
			break;

		case 'l':
			listen_addr_str = optarg;
			break;

		default:
			FATAL("Unknown option %c: %s", arg, argv[optind]);
		}
	}

	if (optind != argc) {
		FATAL("Usage: %s [--buf-size=<>] [--threads=<>] [--polling] "
		      "[--reuseport] [--listen=]",
		      argv[0]);
	}

	struct net_addr listen_addr;
	parse_addr(&listen_addr, listen_addr_str);

	int main_fd = -1;
	if (reuseport == 0) {
		fprintf(stderr,
			"[*] Starting udpreceiver on %s, "
			"polling=%i, busy_poll=%i, threads=%i, reuseport=%i\n",
			addr_to_str(&listen_addr), polling, busy_poll,
			thread_num, reuseport);

		main_fd = net_bind_udp(&listen_addr, 0, busy_poll);
	}

	struct state *array_of_states =
		calloc(thread_num, sizeof(struct state));

	int t;
	for (t = 0; t < thread_num; t++) {
		struct state *state = &array_of_states[t];
		state_init(state);
		state->polling = polling;
		if (reuseport == 0) {
			state->fd = main_fd;
		} else {
			fprintf(stderr, "[*] Starting udpreceiver on %s\n",
				addr_to_str(&listen_addr));

			int fd = net_bind_udp(&listen_addr, 1, busy_poll);
			state->fd = fd;
		}
		thread_spawn(thread_loop, state);
	}

	while (1) {
		struct timeval timeout = NSEC_TIMEVAL(MSEC_NSEC(1000UL));
		while (1) {
			int r = select(0, NULL, NULL, NULL, &timeout);
			if (r != 0) {
				continue;
			}
			if (TIMEVAL_NSEC(&timeout) == 0) {
				break;
			}
		}
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rsi, %r12
movl %edi, %r13d
leaq 0xe4986(%rip), %rdi     # 0x4e6110
callq 0x40297d
movq %rax, %rbx
movq $0x4e7160, %rax         # imm = 0x4E7160
movl $0x1, (%rax)
leaq 0xb1886(%rip), %rax     # 0x4b302c
movq %rax, -0x40(%rbp)
pushq $0x1
popq %rax
movl $0x0, -0x2c(%rbp)
leaq 0xb1849(%rip), %r14     # 0x4b3004
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl %eax, %r15d
andl $0x0, -0x90(%rbp)
movl %r13d, %edi
movq %r12, %rsi
movq %rbx, %rdx
leaq 0xe492d(%rip), %rcx     # 0x4e6110
leaq -0x90(%rbp), %r8
callq 0x45bb40
cmpl $-0x1, %eax
je 0x401853
leal -0x62(%rax), %ecx
rorl %ecx
cmpl $0x9, %ecx
ja 0x4019a2
movslq (%r14,%rcx,4), %rcx
addq %r14, %rcx
jmpq *%rcx
movq $0x4eda80, %rax         # imm = 0x4EDA80
movq (%rax), %rdi
callq 0x40b230
movl %eax, -0x2c(%rbp)
jmp 0x4017cc
pushq $0x1
popq %rax
movl %eax, -0x30(%rbp)
jmp 0x4017cc
pushq $0x1
popq %rax
movl %eax, -0x34(%rbp)
jmp 0x4017cc
movq $0x4eda80, %rax         # imm = 0x4EDA80
movq (%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x4017cc
movq $0x4eda80, %rax         # imm = 0x4EDA80
movq (%rax), %rdi
callq 0x40b230
jmp 0x4017c9
movq $0x4e7160, %rax         # imm = 0x4E7160
cmpl %r13d, (%rax)
jne 0x4019f7
leaq -0x90(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x401b8f
cmpl $0x0, -0x34(%rbp)
je 0x401952
pushq $-0x1
popq %rbx
movslq %r15d, %rdi
movl $0x1800, %esi           # imm = 0x1800
callq 0x4264a0
movq %rax, %r12
xorl %eax, %eax
testl %r15d, %r15d
cmovlel %eax, %r15d
leaq 0x193(%rip), %r13       # 0x401a33
subq $0x1, %r15
jb 0x401918
movq %r12, %rdi
callq 0x401718
movl -0x30(%rbp), %eax
movl %eax, 0x4(%r12)
movl %ebx, %eax
cmpl $0x0, -0x34(%rbp)
jne 0x4018d6
movl %eax, (%r12)
movq %r13, %rdi
movq %r12, %rsi
callq 0x4022aa
addq $0x1800, %r12           # imm = 0x1800
jmp 0x4018a0
movq $0x4e67c8, %rax         # imm = 0x4E67C8
movq (%rax), %rax
movq %rax, -0x40(%rbp)
leaq -0x90(%rbp), %r14
movq %r14, %rdi
callq 0x401da8
movq -0x40(%rbp), %rdi
leaq 0xb186e(%rip), %rsi     # 0x4b316c
movq %rax, %rdx
xorl %eax, %eax
callq 0x40ce50
movq %r14, %rdi
pushq $0x1
popq %rsi
movl -0x2c(%rbp), %edx
callq 0x401e2d
jmp 0x4018be
leaq -0x50(%rbp), %rbx
movups 0xb18dd(%rip), %xmm0    # 0x4b3200
movaps %xmm0, -0x50(%rbp)
xorl %edi, %edi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
movq %rbx, %r8
callq 0x45cd80
testl %eax, %eax
jne 0x401927
imulq $0x3b9aca00, -0x50(%rbp), %rax # imm = 0x3B9ACA00
imulq $-0x3e8, -0x48(%rbp), %rcx # imm = 0xFC18
cmpq %rcx, %rax
jne 0x401927
jmp 0x40191c
movq $0x4e67c8, %rax         # imm = 0x4E67C8
movq (%rax), %rbx
leaq -0x90(%rbp), %r12
movq %r12, %rdi
callq 0x401da8
andl $0x0, (%rsp)
leaq 0xb17a2(%rip), %rsi     # 0x4b3118
movq %rbx, %rdi
movq %rax, %rdx
movl -0x30(%rbp), %ecx
movl -0x2c(%rbp), %ebx
movl %ebx, %r8d
movl %r15d, %r9d
xorl %eax, %eax
callq 0x40ce50
movq %r12, %rdi
xorl %esi, %esi
movl %ebx, %edx
callq 0x401e2d
movl %eax, %ebx
jmp 0x401880
movq $0x4e67c8, %rbx         # imm = 0x4E67C8
movq (%rbx), %rdi
movq $0x4e7160, %rcx         # imm = 0x4E7160
movslq (%rcx), %rcx
movq (%r12,%rcx,8), %rcx
leaq 0xb16a3(%rip), %rsi     # 0x4b3064
movl %eax, %edx
xorl %eax, %eax
callq 0x40ce50
movq (%rbx), %rdi
leaq 0xb16ba(%rip), %rsi     # 0x4b308e
leaq 0xc8c52(%rip), %rdx     # 0x4ca62d
leaq 0xb16c7(%rip), %rcx     # 0x4b30a9
movl $0x80, %r8d
xorl %eax, %eax
callq 0x40ce50
pushq $0x1
popq %rdi
callq 0x40bdb0
movq $0x4e67c8, %rbx         # imm = 0x4E67C8
movq (%rbx), %rdi
movq (%r12), %rdx
leaq 0xb16a9(%rip), %rsi     # 0x4b30b5
xorl %eax, %eax
callq 0x40ce50
movq (%rbx), %rdi
leaq 0xb1671(%rip), %rsi     # 0x4b308e
leaq 0xc8c09(%rip), %rdx     # 0x4ca62d
leaq 0xb167e(%rip), %rcx     # 0x4b30a9
movl $0x87, %r8d
jmp 0x4019e8