// File: /workspace/github_c_makefile_star2_O2/sprt[P]lossless-transport/src/sender.c
// Function: main_loop
void main_loop(void) {
	/* Initialize the set inside the loop as it is mutated by select */
	fd_set read_fds;
	FD_ZERO(&read_fds);
	FD_SET(sockfd, &read_fds);

	if (!sent_eof && window_buffer_size(w) == 0 && window_get_size(w) == 0) {
		log_msg("---------- Waiting indefinitely...\n");
		log_msg("Window: [%zu, %zu], buffer: %zu/%zu\n", window_start(w),
			window_end(w), window_buffer_size(w), window_get_size(w));

		if (select(sockfd + 1, &read_fds, NULL, NULL, NULL) == -1) {
			exit_perror("select");
		}
	} else {
		/* Timeout will be zero unless the buffer is full or EOF was sent */
		uint32_t timeout_us = get_timeout();
		struct timeval timeout_tv = micro_to_timeval(timeout_us);

		log_msg("---------- Waiting for %.3fs...\n", (double) timeout_us / 1000000);
		log_msg("Window: [%zu, %zu], buffer: %zu/%zu\n", window_start(w),
			window_end(w), window_buffer_size(w), window_get_size(w));

		/* Wait until either we receive data on the socket
		* or the timeout expires */
		if (select(sockfd + 1, &read_fds, NULL, NULL, &timeout_tv) == -1) {
			exit_perror("select");
		}
	}

	/* Received an ACK or a NACK */
	if (FD_ISSET(sockfd, &read_fds)) {
		char buf[MAX_PACKET_SIZE];
		int len = recv(sockfd, buf, MAX_PACKET_SIZE, 0);
		if (len == -1) {
			exit_perror("recv");
		}

		pkt_t *resp = pkt_new();
		if (resp == NULL) {
			exit_msg("Could not allocate packet\n");
		}

		pkt_status_code err = pkt_decode(buf, len, resp);

		if (err != PKT_OK) {
			log_msg("Error decoding packet (%s), ignoring\n",
				pkt_code_to_str(err));
		} else {
			log_msg("< %s\n", pkt_repr(resp));

			switch (pkt_get_type(resp)) {
			case PTYPE_DATA:
				log_msg("Received DATA packet, ignoring\n");
				return;

			case PTYPE_ACK:
				log_msg("Received ACK for #%d\n", pkt_get_seqnum(resp) - 1);
				handle_ack(resp);
				break;

			case PTYPE_NACK:
				log_msg("Received NACK for #%d\n", pkt_get_seqnum(resp));
				handle_nack(resp);
				break;

			/* other cases guarded by pkt_decode above */
			}

			/* We handled an ACK or a NACK, so resize the sending
			 * window according to the receiving window so as not to
			 * overload the receiver. */
			size_t swin = window_get_max_size(w);
			size_t rwin = pkt_get_window(resp);
			size_t new_win_size = MIN(swin, rwin);
			assert(window_resize(w, new_win_size) == 0);
			log_msg("New window size: %zu\n", new_win_size);
		}

		pkt_del(resp);

		log_msg("Window: [%zu, %zu], buffer: %zu/%zu\n", window_start(w),
			window_end(w), window_buffer_size(w), window_get_size(w));
	}

	retransmit_packets();

	/* If the window isn't full and we still have data to read,
	 * just keep filling up the buffer */
	if (!window_full(w) && !sent_eof) {
		char buf[MAX_PAYLOAD_SIZE] = {0};
		size_t len = fread(buf, sizeof (*buf), MAX_PAYLOAD_SIZE, infile);

		if (len < MAX_PAYLOAD_SIZE) { /* either error or EOF */
			if (ferror(infile)) {
				exit_msg("Error reading from file\n");
			}
			log_msg("Read EOF\n");
		}

		pkt_t *pkt = pkt_new();
		if (pkt == NULL) {
			exit_msg("Error creating packet\n");
		}

		pkt_status_code err = PKT_OK;
		err = err || pkt_set_type(pkt, PTYPE_DATA);
		err = err || pkt_set_seqnum(pkt, next);
		/* The sender has no receiving window */
		err = err || pkt_set_window(pkt, 0);
		err = err || pkt_set_timestamp(pkt, get_monotime() + TIMER);
		err = err || pkt_set_payload(pkt, buf, len);

		if (err != PKT_OK) {
			exit_msg("Could not create packet: %d\n", err);
		}

		if (send_packet(sockfd, pkt) == -1) {
			exit_perror("send");
		}

		/* Packet is in-flight and non-acknowledged,
		 * hence add it to the buffer */
		if (window_push(w, pkt) == -1) {
			exit_msg("Could not add packet to buffer\n");
		}

		next = (next + 1) % 256;

		log_msg("> %s\n", pkt_repr(pkt));
		log_msg("Added packet #%d to buffer\n", pkt_get_seqnum(pkt));

		if (len == 0) {
			log_msg("Sent EOF packet\n");
			sent_eof = true;
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x298, %rsp            # imm = 0x298
xorl %eax, %eax
cmpq $0x10, %rax
je 0x232b
andq $0x0, (%rsp,%rax,8)
incq %rax
jmp 0x231b
movl 0x3de7(%rip), %ecx      # 0x6118
pushq $0x40
popq %r13
movl %ecx, %eax
cltd
idivl %r13d
movslq %eax, %rdx
shll $0x6, %eax
subl %eax, %ecx
pushq $0x1
popq %rax
shlq %cl, %rax
orq %rax, (%rsp,%rdx,8)
cmpb $0x0, 0x4214(%rip)      # 0x6568
jne 0x237c
movq 0x4203(%rip), %rdi      # 0x6560
callq 0x1e5c
testq %rax, %rax
jne 0x237c
movq 0x41f2(%rip), %rdi      # 0x6560
callq 0x1ddf
testq %rax, %rax
je 0x250f
callq 0x2054
movl %eax, %ebp
movl %eax, %edi
callq 0x1caf
leaq 0x80(%rsp), %rbx
movq %rax, (%rbx)
movq %rdx, 0x8(%rbx)
movl %ebp, %eax
cvtsi2sd %rax, %xmm0
divsd 0xe58(%rip), %xmm0      # 0x3200
leaq 0xffa(%rip), %rdi       # 0x33a9
movb $0x1, %al
callq 0x170e
movq 0x41a3(%rip), %rdi      # 0x6560
callq 0x1d24
movq %rax, %r14
movq 0x4194(%rip), %rdi      # 0x6560
callq 0x1d29
movq %rax, %r15
movq 0x4185(%rip), %rdi      # 0x6560
callq 0x1e5c
movq %rax, %r12
movq 0x4176(%rip), %rdi      # 0x6560
callq 0x1ddf
leaq 0xf87(%rip), %rdi       # 0x337d
movq %r14, %rsi
movq %r15, %rdx
movq %r12, %rcx
movq %rax, %r8
xorl %eax, %eax
callq 0x170e
movl 0x3d09(%rip), %edi      # 0x6118
incl %edi
movq %rsp, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movq %rbx, %r8
callq 0x1130
cmpl $-0x1, %eax
jne 0x2431
leaq 0xf76(%rip), %rdi       # 0x33a2
callq 0x1863
movl 0x3ce1(%rip), %edi      # 0x6118
movl %edi, %eax
cltd
idivl %r13d
cltq
movq (%rsp,%rax,8), %rax
btq %rdx, %rax
jae 0x2672
leaq 0x80(%rsp), %rsi
movl $0x210, %edx            # imm = 0x210
xorl %ecx, %ecx
callq 0x1040
movq %rax, %r14
cmpl $-0x1, %r14d
jne 0x2476
leaq 0xf59(%rip), %rdi       # 0x33ca
callq 0x1863
xorl %eax, %eax
callq 0x130c
movq %rax, %rbx
testq %rax, %rax
jne 0x2493
leaq 0xf43(%rip), %rdi       # 0x33cf
xorl %eax, %eax
callq 0x17c3
movslq %r14d, %rsi
leaq 0x80(%rsp), %rdi
movq %rbx, %rdx
callq 0x138f
testl %eax, %eax
je 0x24c0
movl %eax, %edi
callq 0x1571
leaq 0xf32(%rip), %rdi       # 0x33ea
movq %rax, %rsi
jmp 0x2610
movq %rbx, %rdi
callq 0x18cb
leaq 0xf41(%rip), %rdi       # 0x3410
movq %rax, %rsi
xorl %eax, %eax
callq 0x170e
movq %rbx, %rdi
callq 0x1467
cmpl $0x3, %eax
je 0x25ac
cmpl $0x2, %eax
je 0x2587
cmpl $0x1, %eax
jne 0x25cd
leaq 0xf13(%rip), %rdi       # 0x3416
xorl %eax, %eax
callq 0x170e
jmp 0x2828
leaq 0xe43(%rip), %rdi       # 0x3359
xorl %eax, %eax
callq 0x170e
movq 0x403c(%rip), %rdi      # 0x6560
callq 0x1d24
movq %rax, %rbx
movq 0x402d(%rip), %rdi      # 0x6560
callq 0x1d29
movq %rax, %r14
movq 0x401e(%rip), %rdi      # 0x6560
callq 0x1e5c
movq %rax, %r15
movq 0x400f(%rip), %rdi      # 0x6560
callq 0x1ddf
leaq 0xe20(%rip), %rdi       # 0x337d
movq %rbx, %rsi
movq %r14, %rdx
movq %r15, %rcx
movq %rax, %r8
xorl %eax, %eax
callq 0x170e
movl 0x3ba2(%rip), %edi      # 0x6118
incl %edi
movq %rsp, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
jmp 0x241b
movq %rbx, %rdi
callq 0x158f
movzbl %al, %esi
decl %esi
leaq 0xe9b(%rip), %rdi       # 0x3436
xorl %eax, %eax
callq 0x170e
movq %rbx, %rdi
callq 0x20a3
jmp 0x25cd
movq %rbx, %rdi
callq 0x158f
movzbl %al, %esi
leaq 0xe8e(%rip), %rdi       # 0x344c
xorl %eax, %eax
callq 0x170e
movq %rbx, %rdi
callq 0x21d1
movq 0x3f8c(%rip), %rdi      # 0x6560
callq 0x1dda
movq %rax, %r15
movq %rbx, %rdi
callq 0x1476
movzbl %al, %r14d
cmpq %r14, %r15
cmovbq %r15, %r14
movq 0x3f6a(%rip), %rdi      # 0x6560
movq %r14, %rsi
callq 0x1dc9
testl %eax, %eax
jne 0x283a
leaq 0xe8f(%rip), %rdi       # 0x349c
movq %r14, %rsi
xorl %eax, %eax
callq 0x170e
movq %rbx, %rdi
callq 0x1319
movq 0x3f3a(%rip), %rdi      # 0x6560
callq 0x1d24
movq %rax, %rbx
movq 0x3f2b(%rip), %rdi      # 0x6560
callq 0x1d29
movq %rax, %r14
movq 0x3f1c(%rip), %rdi      # 0x6560
callq 0x1e5c
movq %rax, %r15
movq 0x3f0d(%rip), %rdi      # 0x6560
callq 0x1ddf
leaq 0xd1e(%rip), %rdi       # 0x337d
movq %rbx, %rsi
movq %r14, %rdx
movq %r15, %rcx
movq %rax, %r8
xorl %eax, %eax
callq 0x170e
callq 0x2249
movq 0x3ee2(%rip), %rdi      # 0x6560
callq 0x1e39
testb %al, %al
jne 0x2828
cmpb $0x0, 0x3ed6(%rip)      # 0x6568
jne 0x2828
leaq 0x80(%rsp), %rbx
movl $0x200, %edx            # imm = 0x200
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10f0
movq 0x3eba(%rip), %rcx      # 0x6570
pushq $0x1
popq %rsi
movl $0x200, %edx            # imm = 0x200
movq %rbx, %rdi
callq 0x1080
movq %rax, %rbx
cmpq $0x1ff, %rax            # imm = 0x1FF
ja 0x26fd
movq 0x3e98(%rip), %rdi      # 0x6570
callq 0x1070
testl %eax, %eax
je 0x26ef
leaq 0xdca(%rip), %rdi       # 0x34b2
xorl %eax, %eax
callq 0x17c3
leaq 0xdd5(%rip), %rdi       # 0x34cb
xorl %eax, %eax
callq 0x170e
xorl %eax, %eax
callq 0x130c
movq %rax, %r14
testq %rax, %rax
jne 0x271a
leaq 0xdc2(%rip), %rdi       # 0x34d5
xorl %eax, %eax
callq 0x17c3
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x15b0
testl %eax, %eax
jne 0x2778
movzbl 0x3e28(%rip), %esi      # 0x6558
movq %r14, %rdi
callq 0x15fc
testl %eax, %eax
jne 0x2778
movq %r14, %rdi
xorl %esi, %esi
callq 0x15e6
testl %eax, %eax
jne 0x2778
callq 0x1bd1
leal 0x44aa20(%rax), %esi
movq %r14, %rdi
callq 0x1645
testl %eax, %eax
jne 0x2778
movzwl %bx, %edx
leaq 0x80(%rsp), %rsi
movq %r14, %rdi
callq 0x164d
testl %eax, %eax
je 0x2789
leaq 0xd6d(%rip), %rdi       # 0x34ec
pushq $0x1
popq %rsi
xorl %eax, %eax
callq 0x17c3
movl 0x3989(%rip), %edi      # 0x6118
movq %r14, %rsi
callq 0x1b7d
cmpl $-0x1, %eax
jne 0x27a8
leaq 0xba6(%rip), %rdi       # 0x3349
callq 0x1863
movq 0x3db1(%rip), %rdi      # 0x6560
movq %r14, %rsi
callq 0x1de4
cmpl $-0x1, %eax
jne 0x27ca
leaq 0xd46(%rip), %rdi       # 0x3509
xorl %eax, %eax
callq 0x17c3
movl 0x3d88(%rip), %eax      # 0x6558
incl %eax
movzbl %al, %eax
movq %rax, 0x3d7c(%rip)      # 0x6558
movq %r14, %rdi
callq 0x18cb
leaq 0xd3e(%rip), %rdi       # 0x3529
movq %rax, %rsi
xorl %eax, %eax
callq 0x170e
movq %r14, %rdi
callq 0x158f
movzbl %al, %esi
leaq 0xd28(%rip), %rdi       # 0x352f
xorl %eax, %eax
callq 0x170e
testq %rbx, %rbx
jne 0x2828
leaq 0xd31(%rip), %rdi       # 0x354b
xorl %eax, %eax
callq 0x170e
movb $0x1, 0x3d40(%rip)      # 0x6568
addq $0x298, %rsp            # imm = 0x298
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xc22(%rip), %rdi       # 0x3463
leaq 0x9eb(%rip), %rsi       # 0x3233
leaq 0xc38(%rip), %rcx       # 0x3487
movl $0xd0, %edx
callq 0x10e0