// File: /workspace/github_c_makefile_star2_O1/unixlab[P]cloudflare-udp-ping/udpclient.c
// Function: thread_loop
void thread_loop(void *userdata)
{
	struct state *state = userdata;

	pthread_spin_init(&state->lock, PTHREAD_PROCESS_PRIVATE);

	char send_buf[PKT_SIZE], recv_buf[PKT_SIZE];
	struct msghdr *msg = calloc(2, sizeof(struct msghdr));
	struct iovec *iovec = calloc(2, sizeof(struct iovec));
	int i;
	for (i = 0; i < 2; i++) {
		msg[i].msg_iov = &iovec[i];
		msg[i].msg_iovlen = 1;
		iovec[i].iov_len = sizeof(send_buf);
	}

	iovec[0].iov_base = send_buf;
	iovec[1].iov_base = recv_buf;

	char pktinfo[4096];
	msg[1].msg_control = pktinfo;
	msg[1].msg_controllen = sizeof(pktinfo);

	uint64_t packet_no = 0;
	while (1) {
		int fd = net_connect_udp(state->target_addr, state->src_port,
					 state->busy_poll);

		struct timeval tv = {1, 0}; // 1 second
		int r = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv,
				   sizeof(tv));
		if (r < 0) {
			PFATAL("setsockopt(SO_RCVTIMEO)");
		}

		for (;; packet_no++) {
			memset(send_buf, 0, sizeof(send_buf));
			snprintf(send_buf, sizeof(send_buf), "%i-%li-%lu",
				 getpid(), gettid(), packet_no);

			uint64_t t0 = realtime_now(), t1 = 0, tp = 0;
			int r = sendmsg(fd, &msg[0], 0);
			if (r <= 0) {
				if (errno == EAGAIN || errno == EWOULDBLOCK ||
				    errno == ECONNREFUSED) {
					break;
				}
				if (errno == EINTR) {
					continue;
				}
				PFATAL("sendmmsg()");
			}

			msg[1].msg_controllen = sizeof(pktinfo);
			while (1) {
				int flags = state->polling ? MSG_DONTWAIT : 0;
				r = recvmsg(fd, &msg[1], flags);
				t1 = realtime_now();
				if (t1 - t0 >= 1000000000) {
					/* No msg for 1s */
					errno = ECONNREFUSED;
					break;
				}

				if (r <= 0 &&
				    (errno == EINTR || errno == EAGAIN ||
				     errno == EWOULDBLOCK)) {
					continue;
				}

				if (r == 0 && state->polling) {
					continue;
				}
				break;
			}

			if (r <= 0 && errno == ECONNREFUSED) {
				sleep(1);
				break;
			}

			if (r <= 0) {
				PFATAL("recvmmsg()");
			}

			if (memcmp(send_buf, recv_buf, sizeof(recv_buf)) != 0) {
				fprintf(stderr, "[!] bad message\n");
				sleep(1);
				break;
			}

			struct cmsghdr *cmsg;
			for (cmsg = CMSG_FIRSTHDR(&msg[1]); cmsg;
			     cmsg = CMSG_NXTHDR(&msg[1], cmsg)) {
				switch (cmsg->cmsg_level) {
				case SOL_SOCKET:
					switch (cmsg->cmsg_type) {
					case SO_TIMESTAMPNS: {
						struct timespec *ts =
							(struct timespec *)
							CMSG_DATA(cmsg);
						tp = TIMESPEC_NSEC(ts);
						break;
					}
					}
					break;
				}
			}

			pthread_spin_lock(&state->lock);
			stddev_add(&state->stddev, t1 - t0);
			if (tp != 0) {
				stddev_add(&state->stddev_packet, t1 - tp);
			}
			pthread_spin_unlock(&state->lock);
		}
		close(fd);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1078, %rsp           # imm = 0x1078
movq %rdi, -0x38(%rbp)
addq $0x14, %rdi
movq %rdi, -0x48(%rbp)
xorl %esi, %esi
callq 0x421150
movl $0x2, %edi
movl $0x38, %esi
callq 0x426fe0
movq %rax, %r15
movq %rax, %rbx
movl $0x2, %edi
movl $0x10, %esi
callq 0x426fe0
movl $0x18, %ecx
movq %rax, %rdx
movq %rdx, -0x8(%rbx,%rcx)
movq $0x1, (%rbx,%rcx)
movq $0x20, 0x8(%rdx)
addq $0x38, %rcx
addq $0x10, %rdx
cmpq $0x50, %rcx
je 0x40221b
leaq -0x70(%rbp), %rcx
movq %rcx, (%rax)
leaq -0xa0(%rbp), %rcx
movq %rcx, 0x10(%rax)
addq $0x38, %r15
leaq -0x10a0(%rbp), %rax
movq %rax, 0x58(%rbx)
movq $0x1000, 0x60(%rbx)     # imm = 0x1000
xorl %r13d, %r13d
movq %rbx, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rdi
movl 0x8(%rax), %esi
movl 0x10(%rax), %edx
callq 0x402f76
movl %eax, %r14d
movdqu 0xb1db5(%rip), %xmm0    # 0x4b4040
movdqa %xmm0, -0x80(%rbp)
movl %eax, %edi
movl $0x1, %esi
movl $0x14, %edx
leaq -0x80(%rbp), %rcx
movl $0x10, %r8d
callq 0x45fc40
testl %eax, %eax
movl %r14d, -0x2c(%rbp)
js 0x402568
pxor %xmm0, %xmm0
movdqa %xmm0, -0x60(%rbp)
movdqa %xmm0, -0x70(%rbp)
callq 0x45af80
movl %eax, %r14d
callq 0x45f5f0
movl $0x20, %esi
leaq -0x70(%rbp), %rdi
leaq 0xb1ded(%rip), %rdx     # 0x4b40cf
movl %r14d, %ecx
movl -0x2c(%rbp), %r14d
movl %eax, %r8d
movq %r13, %r9
xorl %eax, %eax
callq 0x40d910
xorl %eax, %eax
callq 0x40323b
movq %rax, %r12
movl %r14d, %edi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x45fba0
testl %eax, %eax
jle 0x4023e6
movq %r13, -0x50(%rbp)
movq $0x1000, 0x60(%rbx)     # imm = 0x1000
xorl %edx, %edx
movq -0x38(%rbp), %rax
cmpl $0x0, 0xc(%rax)
setne %dl
shll $0x6, %edx
movl %r14d, %edi
movq %r15, %rsi
callq 0x45faf0
movq %rax, %r14
xorl %eax, %eax
callq 0x40323b
movq %rax, %rbx
movq %rax, %r13
subq %r12, %r13
cmpq $0x3b9ac9ff, %r13       # imm = 0x3B9AC9FF
ja 0x402394
testl %r14d, %r14d
jle 0x402381
testl %r14d, %r14d
jne 0x40239f
movq -0x38(%rbp), %rax
cmpl $0x0, 0xc(%rax)
je 0x40239f
xorl %edx, %edx
movq -0x38(%rbp), %rax
cmpl $0x0, 0xc(%rax)
setne %dl
shll $0x6, %edx
movl -0x2c(%rbp), %edi
jmp 0x402334
callq 0x405e80
movl (%rax), %eax
cmpl $0x4, %eax
je 0x40236c
cmpl $0xb, %eax
je 0x40236c
jmp 0x40235d
callq 0x405e80
movl $0x6f, (%rax)
testl %r14d, %r14d
jle 0x4024a9
movdqa -0x70(%rbp), %xmm0
movdqa -0x60(%rbp), %xmm1
pcmpeqb -0x90(%rbp), %xmm1
pcmpeqb -0xa0(%rbp), %xmm0
pand %xmm1, %xmm0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x4024da
movq -0x40(%rbp), %rax
cmpq $0x10, 0x60(%rax)
jb 0x4023fb
movq 0x58(%rax), %rax
jmp 0x4023fd
callq 0x405e80
movl (%rax), %eax
cmpl $0x4, %eax
je 0x402495
jmp 0x40249d
xorl %eax, %eax
xorl %r14d, %r14d
testq %rax, %rax
je 0x40242a
cmpl $0x1, 0x8(%rax)
jne 0x40241d
cmpl $0x23, 0xc(%rax)
jne 0x40241d
imulq $0x3b9aca00, 0x10(%rax), %r14 # imm = 0x3B9ACA00
addq 0x18(%rax), %r14
movq %r15, %rdi
movq %rax, %rsi
callq 0x45fcb0
jmp 0x402400
movq -0x48(%rbp), %rdi
callq 0x421130
movq -0x38(%rbp), %rdx
incq 0x30(%rdx)
movslq %r13d, %rax
addq %rax, 0x20(%rdx)
movl %eax, %ecx
imull %ecx, %ecx
addq %rcx, 0x28(%rdx)
cmpl %eax, 0x18(%rdx)
jle 0x402458
movq -0x38(%rbp), %rax
movl %r13d, 0x18(%rax)
testq %r14, %r14
je 0x402484
subq %r14, %rbx
movq -0x38(%rbp), %rdx
incq 0x50(%rdx)
movslq %ebx, %rax
addq %rax, 0x40(%rdx)
movl %eax, %ecx
imull %ecx, %ecx
addq %rcx, 0x48(%rdx)
cmpl %eax, 0x38(%rdx)
jle 0x402484
movq -0x38(%rbp), %rax
movl %ebx, 0x38(%rax)
movq -0x48(%rbp), %rdi
callq 0x421150
movq -0x40(%rbp), %rbx
movq -0x50(%rbp), %r13
incq %r13
jmp 0x4022b7
cmpl $0xb, %eax
je 0x4024cd
cmpl $0x6f, %eax
je 0x4024cd
jmp 0x402500
callq 0x405e80
cmpl $0x6f, (%rax)
movl -0x2c(%rbp), %r14d
jne 0x4025a8
movl $0x1, %edi
callq 0x45ae80
movq -0x40(%rbp), %rbx
movq -0x50(%rbp), %r13
movl %r14d, %edi
callq 0x45cd70
jmp 0x40226e
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rcx
movl $0x10, %esi
movl $0x1, %edx
leaq 0xb1c21(%rip), %rdi     # 0x4b4116
callq 0x4147e0
movl -0x2c(%rbp), %r14d
jmp 0x4024bb
movq $0x4e87a8, %rbx         # imm = 0x4E87A8
movq (%rbx), %rcx
leaq 0xb1bc9(%rip), %rdi     # 0x4b40da
movl $0x1d, %esi
movl $0x1, %edx
callq 0x4147e0
movq (%rbx), %rdi
leaq 0xb1b61(%rip), %rsi     # 0x4b408b
leaq 0xb1b74(%rip), %rdx     # 0x4b40a5
leaq 0xb1b79(%rip), %rcx     # 0x4b40b1
movl $0x53, %r8d
xorl %eax, %eax
callq 0x40d780
leaq 0xb1b71(%rip), %rdi     # 0x4b40bd
callq 0x40db30
movq (%rbx), %rsi
movl $0xa, %edi
callq 0x416b50
movl $0x1, %edi
callq 0x40c6e0
movq $0x4e87a8, %rbx         # imm = 0x4E87A8
movq (%rbx), %rcx
leaq 0xb1ae7(%rip), %rdi     # 0x4b4060
movl $0x2a, %esi
movl $0x1, %edx
callq 0x4147e0
movq (%rbx), %rdi
leaq 0xb1af9(%rip), %rsi     # 0x4b408b
leaq 0xb1b0c(%rip), %rdx     # 0x4b40a5
leaq 0xb1b11(%rip), %rcx     # 0x4b40b1
movl $0x41, %r8d
jmp 0x40253e
movq $0x4e87a8, %rbx         # imm = 0x4E87A8
movq (%rbx), %rcx
leaq 0xb1b3f(%rip), %rdi     # 0x4b40f8
movl $0x1d, %esi
movl $0x1, %edx
callq 0x4147e0
movq (%rbx), %rdi
leaq 0xb1ab9(%rip), %rsi     # 0x4b408b
leaq 0xb1acc(%rip), %rdx     # 0x4b40a5
leaq 0xb1ad1(%rip), %rcx     # 0x4b40b1
movl $0x73, %r8d
jmp 0x40253e