// File: /workspace/github_c_makefile_star2_O0/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
subq $0x10e0, %rsp           # imm = 0x10E0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
addq $0x14, %rdi
xorl %esi, %esi
callq 0x421500
movl $0x2, %edi
movl $0x38, %esi
callq 0x427390
movq %rax, -0x58(%rbp)
movl $0x2, %edi
movl $0x10, %esi
callq 0x427390
movq %rax, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
cmpl $0x2, -0x64(%rbp)
jge 0x401794
movq -0x60(%rbp), %rcx
movslq -0x64(%rbp), %rax
shlq $0x4, %rax
addq %rax, %rcx
movq -0x58(%rbp), %rax
movslq -0x64(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movq -0x58(%rbp), %rax
movslq -0x64(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq $0x1, 0x18(%rax)
movq -0x60(%rbp), %rax
movslq -0x64(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq $0x20, 0x8(%rax)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x401733
leaq -0x30(%rbp), %rcx
movq -0x60(%rbp), %rax
movq %rcx, (%rax)
leaq -0x50(%rbp), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x10(%rax)
leaq -0x1070(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rcx, 0x58(%rax)
movq -0x58(%rbp), %rax
movq $0x1000, 0x60(%rax)     # imm = 0x1000
movq $0x0, -0x1078(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x403170
movl %eax, -0x107c(%rbp)
movq 0xb3898(%rip), %rax     # 0x4b5090
movq %rax, -0x1090(%rbp)
movq 0xb3892(%rip), %rax     # 0x4b5098
movq %rax, -0x1088(%rbp)
movl -0x107c(%rbp), %edi
movl $0x1, %esi
movl $0x14, %edx
leaq -0x1090(%rbp), %rcx
movl $0x10, %r8d
callq 0x460040
movl %eax, -0x1094(%rbp)
cmpl $0x0, -0x1094(%rbp)
jge 0x4018b2
jmp 0x401840
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb384f(%rip), %rsi     # 0x4b50a0
movb $0x0, %al
callq 0x40df10
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb3862(%rip), %rsi     # 0x4b50cb
leaq 0xb3875(%rip), %rdx     # 0x4b50e5
leaq 0xb387a(%rip), %rcx     # 0x4b50f1
movl $0x41, %r8d
movb $0x0, %al
callq 0x40df10
leaq 0xb3872(%rip), %rdi     # 0x4b50fd
callq 0x40e2c0
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb4269(%rip), %rsi     # 0x4b5b0a
movb $0x0, %al
callq 0x40df10
movl $0x1, %edi
callq 0x40ce70
jmp 0x4018b4
leaq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x4010a8
leaq -0x30(%rbp), %rax
movq %rax, -0x10d8(%rbp)
callq 0x45b340
movl %eax, -0x10cc(%rbp)
callq 0x45f9b0
movq -0x10d8(%rbp), %rdi
movl -0x10cc(%rbp), %ecx
movl %eax, %r8d
movq -0x1078(%rbp), %r9
movl $0x20, %esi
leaq 0xb380d(%rip), %rdx     # 0x4b510f
movb $0x0, %al
callq 0x40e0a0
movb $0x0, %al
callq 0x403950
movq %rax, -0x10a0(%rbp)
movq $0x0, -0x10a8(%rbp)
movq $0x0, -0x10b0(%rbp)
movl -0x107c(%rbp), %edi
movq -0x58(%rbp), %rsi
xorl %edx, %edx
callq 0x45ffa0
movl %eax, -0x10b4(%rbp)
cmpl $0x0, -0x10b4(%rbp)
jg 0x4019f7
callq 0x406610
cmpl $0xb, (%rax)
je 0x40196f
callq 0x406610
cmpl $0xb, (%rax)
je 0x40196f
callq 0x406610
cmpl $0x6f, (%rax)
jne 0x401974
jmp 0x401cb9
callq 0x406610
cmpl $0x4, (%rax)
jne 0x401983
jmp 0x401ca2
jmp 0x401985
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb3784(%rip), %rsi     # 0x4b511a
movb $0x0, %al
callq 0x40df10
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb371d(%rip), %rsi     # 0x4b50cb
leaq 0xb3730(%rip), %rdx     # 0x4b50e5
leaq 0xb3735(%rip), %rcx     # 0x4b50f1
movl $0x53, %r8d
movb $0x0, %al
callq 0x40df10
leaq 0xb372d(%rip), %rdi     # 0x4b50fd
callq 0x40e2c0
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb4124(%rip), %rsi     # 0x4b5b0a
movb $0x0, %al
callq 0x40df10
movl $0x1, %edi
callq 0x40ce70
movq -0x58(%rbp), %rax
movq $0x1000, 0x60(%rax)     # imm = 0x1000
movq -0x10(%rbp), %rax
movl 0xc(%rax), %edx
xorl %eax, %eax
movl $0x40, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x10b8(%rbp)
movl -0x107c(%rbp), %edi
movq -0x58(%rbp), %rsi
addq $0x38, %rsi
movl -0x10b8(%rbp), %edx
callq 0x45fef0
movl %eax, -0x10b4(%rbp)
movb $0x0, %al
callq 0x403950
movq %rax, -0x10a8(%rbp)
movq -0x10a8(%rbp), %rax
subq -0x10a0(%rbp), %rax
cmpq $0x3b9aca00, %rax       # imm = 0x3B9ACA00
jb 0x401a6d
callq 0x406610
movl $0x6f, (%rax)
jmp 0x401ab3
cmpl $0x0, -0x10b4(%rbp)
jg 0x401a99
callq 0x406610
cmpl $0x4, (%rax)
je 0x401a94
callq 0x406610
cmpl $0xb, (%rax)
je 0x401a94
callq 0x406610
cmpl $0xb, (%rax)
jne 0x401a99
jmp 0x401a03
cmpl $0x0, -0x10b4(%rbp)
jne 0x401ab1
movq -0x10(%rbp), %rax
cmpl $0x0, 0xc(%rax)
je 0x401ab1
jmp 0x401a03
jmp 0x401ab3
cmpl $0x0, -0x10b4(%rbp)
jg 0x401ad5
callq 0x406610
cmpl $0x6f, (%rax)
jne 0x401ad5
movl $0x1, %edi
callq 0x45b240
jmp 0x401cb9
cmpl $0x0, -0x10b4(%rbp)
jg 0x401b52
jmp 0x401ae0
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb3647(%rip), %rsi     # 0x4b5138
movb $0x0, %al
callq 0x40df10
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb35c2(%rip), %rsi     # 0x4b50cb
leaq 0xb35d5(%rip), %rdx     # 0x4b50e5
leaq 0xb35da(%rip), %rcx     # 0x4b50f1
movl $0x73, %r8d
movb $0x0, %al
callq 0x40df10
leaq 0xb35d2(%rip), %rdi     # 0x4b50fd
callq 0x40e2c0
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb3fc9(%rip), %rsi     # 0x4b5b0a
movb $0x0, %al
callq 0x40df10
movl $0x1, %edi
callq 0x40ce70
leaq -0x30(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movl $0x20, %edx
callq 0x401090
cmpl $0x0, %eax
je 0x401b90
movq $0x4e87a8, %rax         # imm = 0x4E87A8
movq (%rax), %rdi
leaq 0xb35dc(%rip), %rsi     # 0x4b5156
movb $0x0, %al
callq 0x40df10
movl $0x1, %edi
callq 0x45b240
jmp 0x401cb9
movq -0x58(%rbp), %rax
cmpq $0x10, 0x60(%rax)
jb 0x401bac
movq -0x58(%rbp), %rax
movq 0x58(%rax), %rax
movq %rax, -0x10e0(%rbp)
jmp 0x401bb7
xorl %eax, %eax
movq %rax, -0x10e0(%rbp)
jmp 0x401bb7
movq -0x10e0(%rbp), %rax
movq %rax, -0x10c0(%rbp)
cmpq $0x0, -0x10c0(%rbp)
je 0x401c44
movq -0x10c0(%rbp), %rax
movl 0x8(%rax), %eax
subl $0x1, %eax
jne 0x401c25
jmp 0x401be0
movq -0x10c0(%rbp), %rax
movl 0xc(%rax), %eax
subl $0x23, %eax
jne 0x401c23
jmp 0x401bf1
movq -0x10c0(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x10c8(%rbp)
movq -0x10c8(%rbp), %rax
imulq $0x3b9aca00, (%rax), %rax # imm = 0x3B9ACA00
movq -0x10c8(%rbp), %rcx
addq 0x8(%rcx), %rax
movq %rax, -0x10b0(%rbp)
jmp 0x401c25
jmp 0x401c27
movq -0x58(%rbp), %rdi
addq $0x38, %rdi
movq -0x10c0(%rbp), %rsi
callq 0x4600b0
movq %rax, -0x10c0(%rbp)
jmp 0x401bc5
movq -0x10(%rbp), %rdi
addq $0x14, %rdi
callq 0x4214e0
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
movq -0x10a8(%rbp), %rax
subq -0x10a0(%rbp), %rax
movl %eax, %esi
callq 0x401cd0
cmpq $0x0, -0x10b0(%rbp)
je 0x401c95
movq -0x10(%rbp), %rdi
addq $0x38, %rdi
movq -0x10a8(%rbp), %rax
subq -0x10b0(%rbp), %rax
movl %eax, %esi
callq 0x401cd0
movq -0x10(%rbp), %rdi
addq $0x14, %rdi
callq 0x421500
movq -0x1078(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1078(%rbp)
jmp 0x4018b4
movl -0x107c(%rbp), %edi
callq 0x45d130
jmp 0x4017d1
nopl (%rax)