// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x580, %rsp            # imm = 0x580
leaq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
movl $0x0, -0x84(%rbp)
movl -0x84(%rbp), %eax
cmpq $0x10, %rax
jae 0x31d2
movq -0x90(%rbp), %rax
movl -0x84(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x31a0
jmp 0x31d4
movl 0x3f62(%rip), %eax      # 0x713c
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl 0x3f45(%rip), %eax      # 0x713c
movl $0x40, %esi
cltd
idivl %esi
cltq
orq -0x80(%rbp,%rax,8), %rcx
movq %rcx, -0x80(%rbp,%rax,8)
testb $0x1, 0x436e(%rip)      # 0x7580
jne 0x32f0
movq 0x4359(%rip), %rdi      # 0x7578
callq 0x29e0
cmpq $0x0, %rax
jne 0x32f0
movq 0x4343(%rip), %rdi      # 0x7578
callq 0x28a0
cmpq $0x0, %rax
jne 0x32f0
leaq 0x10fe(%rip), %rdi      # 0x4349
movb $0x0, %al
callq 0x1ce0
movq 0x431f(%rip), %rdi      # 0x7578
callq 0x2680
movq %rax, -0x520(%rbp)
movq 0x430c(%rip), %rdi      # 0x7578
callq 0x26a0
movq %rax, -0x518(%rbp)
movq 0x42f9(%rip), %rdi      # 0x7578
callq 0x29e0
movq %rax, -0x510(%rbp)
movq 0x42e6(%rip), %rdi      # 0x7578
callq 0x28a0
movq -0x520(%rbp), %rsi
movq -0x518(%rbp), %rdx
movq -0x510(%rbp), %rcx
movq %rax, %r8
leaq 0x10b7(%rip), %rdi      # 0x436d
movb $0x0, %al
callq 0x1ce0
movl 0x3e79(%rip), %edi      # 0x713c
addl $0x1, %edi
leaq -0x80(%rbp), %rsi
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rdx
movq %r8, %rcx
callq 0x1150
cmpl $-0x1, %eax
jne 0x32eb
leaq 0x10ac(%rip), %rdi      # 0x4392
callq 0x1e60
jmp 0x33d7
callq 0x2df0
movl %eax, -0x94(%rbp)
movl -0x94(%rbp), %edi
callq 0x2550
movq %rax, -0xa8(%rbp)
movq %rdx, -0xa0(%rbp)
movl -0x94(%rbp), %eax
cvtsi2sd %rax, %xmm0
movsd 0xec9(%rip), %xmm1      # 0x41f0
divsd %xmm1, %xmm0
leaq 0x1067(%rip), %rdi      # 0x4399
movb $0x1, %al
callq 0x1ce0
movq 0x4238(%rip), %rdi      # 0x7578
callq 0x2680
movq %rax, -0x538(%rbp)
movq 0x4225(%rip), %rdi      # 0x7578
callq 0x26a0
movq %rax, -0x530(%rbp)
movq 0x4212(%rip), %rdi      # 0x7578
callq 0x29e0
movq %rax, -0x528(%rbp)
movq 0x41ff(%rip), %rdi      # 0x7578
callq 0x28a0
movq -0x538(%rbp), %rsi
movq -0x530(%rbp), %rdx
movq -0x528(%rbp), %rcx
movq %rax, %r8
leaq 0xfd0(%rip), %rdi       # 0x436d
movb $0x0, %al
callq 0x1ce0
movl 0x3d92(%rip), %edi      # 0x713c
addl $0x1, %edi
leaq -0x80(%rbp), %rsi
xorl %eax, %eax
movl %eax, %ecx
leaq -0xa8(%rbp), %r8
movq %rcx, %rdx
callq 0x1150
cmpl $-0x1, %eax
jne 0x33d5
leaq 0xfc2(%rip), %rdi       # 0x4392
callq 0x1e60
jmp 0x33d7
movl 0x3d5f(%rip), %eax      # 0x713c
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq -0x80(%rbp,%rax,8), %rax
movq %rax, -0x540(%rbp)
movl 0x3d43(%rip), %eax      # 0x713c
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x540(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x36ac
movl 0x3d14(%rip), %edi      # 0x713c
leaq -0x2c0(%rbp), %rsi
movl $0x210, %edx            # imm = 0x210
xorl %ecx, %ecx
callq 0x1040
movl %eax, -0x2c4(%rbp)
cmpl $-0x1, -0x2c4(%rbp)
jne 0x3456
leaq 0xf69(%rip), %rdi       # 0x43ba
callq 0x1e60
movb $0x0, %al
callq 0x1350
movq %rax, -0x2d0(%rbp)
cmpq $0x0, -0x2d0(%rbp)
jne 0x347c
leaq 0xf4a(%rip), %rdi       # 0x43bf
movb $0x0, %al
callq 0x1db0
leaq -0x2c0(%rbp), %rdi
movslq -0x2c4(%rbp), %rsi
movq -0x2d0(%rbp), %rdx
callq 0x14b0
movl %eax, -0x2d4(%rbp)
cmpl $0x0, -0x2d4(%rbp)
je 0x34c6
movl -0x2d4(%rbp), %edi
callq 0x18e0
movq %rax, %rsi
leaq 0xf20(%rip), %rdi       # 0x43da
movb $0x0, %al
callq 0x1ce0
jmp 0x3635
movq -0x2d0(%rbp), %rdi
callq 0x1f00
movq %rax, %rsi
leaq 0xf24(%rip), %rdi       # 0x4400
xorl %eax, %eax
callq 0x1ce0
movq -0x2d0(%rbp), %rdi
callq 0x1670
movl %eax, %ecx
movl %ecx, -0x544(%rbp)
subl $0x1, %eax
je 0x3518
jmp 0x34fe
movl -0x544(%rbp), %eax
subl $0x2, %eax
je 0x352b
jmp 0x350b
movl -0x544(%rbp), %eax
subl $0x3, %eax
je 0x3559
jmp 0x3582
leaq 0xee7(%rip), %rdi       # 0x4406
movb $0x0, %al
callq 0x1ce0
jmp 0x39ab
movq -0x2d0(%rbp), %rdi
callq 0x19b0
movzbl %al, %esi
subl $0x1, %esi
leaq 0xee2(%rip), %rdi       # 0x4426
movb $0x0, %al
callq 0x1ce0
movq -0x2d0(%rbp), %rdi
callq 0x2e70
jmp 0x3582
movq -0x2d0(%rbp), %rdi
callq 0x19b0
movzbl %al, %esi
leaq 0xecd(%rip), %rdi       # 0x443c
movb $0x0, %al
callq 0x1ce0
movq -0x2d0(%rbp), %rdi
callq 0x2ff0
movq 0x3fef(%rip), %rdi      # 0x7578
callq 0x2880
movq %rax, -0x2e0(%rbp)
movq -0x2d0(%rbp), %rdi
callq 0x16b0
movzbl %al, %eax
movq %rax, -0x2e8(%rbp)
movq -0x2e0(%rbp), %rax
cmpq -0x2e8(%rbp), %rax
jae 0x35cb
movq -0x2e0(%rbp), %rax
movq %rax, -0x550(%rbp)
jmp 0x35d9
movq -0x2e8(%rbp), %rax
movq %rax, -0x550(%rbp)
movq -0x550(%rbp), %rax
movq %rax, -0x2f0(%rbp)
movq 0x3f8a(%rip), %rdi      # 0x7578
movq -0x2f0(%rbp), %rsi
callq 0x2840
cmpl $0x0, %eax
jne 0x3601
jmp 0x3620
leaq 0xe4b(%rip), %rdi       # 0x4453
leaq 0xc14(%rip), %rsi       # 0x4223
movl $0xd0, %edx
leaq 0xe5c(%rip), %rcx       # 0x4477
callq 0x10f0
movq -0x2f0(%rbp), %rsi
leaq 0xe5e(%rip), %rdi       # 0x448c
movb $0x0, %al
callq 0x1ce0
movq -0x2d0(%rbp), %rdi
callq 0x1370
movq 0x3f30(%rip), %rdi      # 0x7578
callq 0x2680
movq %rax, -0x568(%rbp)
movq 0x3f1d(%rip), %rdi      # 0x7578
callq 0x26a0
movq %rax, -0x560(%rbp)
movq 0x3f0a(%rip), %rdi      # 0x7578
callq 0x29e0
movq %rax, -0x558(%rbp)
movq 0x3ef7(%rip), %rdi      # 0x7578
callq 0x28a0
movq -0x568(%rbp), %rsi
movq -0x560(%rbp), %rdx
movq -0x558(%rbp), %rcx
movq %rax, %r8
leaq 0xcc8(%rip), %rdi       # 0x436d
movb $0x0, %al
callq 0x1ce0
callq 0x3090
movq 0x3ec0(%rip), %rdi      # 0x7578
callq 0x2960
testb $0x1, %al
jne 0x39ab
testb $0x1, 0x3eb4(%rip)      # 0x7580
jne 0x39ab
leaq -0x4f0(%rbp), %rdi
xorl %esi, %esi
movl $0x200, %edx            # imm = 0x200
callq 0x1110
leaq -0x4f0(%rbp), %rdi
movq 0x3e95(%rip), %rcx      # 0x7588
movl $0x1, %esi
movl $0x200, %edx            # imm = 0x200
callq 0x1080
movq %rax, -0x4f8(%rbp)
cmpq $0x200, -0x4f8(%rbp) # imm = 0x200
jae 0x3743
movq 0x3e6b(%rip), %rdi      # 0x7588
callq 0x1070
cmpl $0x0, %eax
je 0x3735
leaq 0xd74(%rip), %rdi       # 0x44a2
movb $0x0, %al
callq 0x1db0
leaq 0xd7f(%rip), %rdi       # 0x44bb
movb $0x0, %al
callq 0x1ce0
movb $0x0, %al
callq 0x1350
movq %rax, -0x500(%rbp)
cmpq $0x0, -0x500(%rbp)
jne 0x3769
leaq 0xd63(%rip), %rdi       # 0x44c5
movb $0x0, %al
callq 0x1db0
movl $0x0, -0x504(%rbp)
movb $0x1, %al
cmpl $0x0, -0x504(%rbp)
movb %al, -0x569(%rbp)
jne 0x37a1
movq -0x500(%rbp), %rdi
movl $0x1, %esi
callq 0x1a30
cmpl $0x0, %eax
setne %al
movb %al, -0x569(%rbp)
movb -0x569(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x504(%rbp)
movb $0x1, %al
cmpl $0x0, -0x504(%rbp)
movb %al, -0x56a(%rbp)
jne 0x37e5
movq -0x500(%rbp), %rdi
movq 0x3d9f(%rip), %rax      # 0x7570
movzbl %al, %esi
callq 0x1b20
cmpl $0x0, %eax
setne %al
movb %al, -0x56a(%rbp)
movb -0x56a(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x504(%rbp)
movb $0x1, %al
cmpl $0x0, -0x504(%rbp)
movb %al, -0x56b(%rbp)
jne 0x3821
movq -0x500(%rbp), %rdi
xorl %esi, %esi
callq 0x1ad0
cmpl $0x0, %eax
setne %al
movb %al, -0x56b(%rbp)
movb -0x56b(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x504(%rbp)
movb $0x1, %al
cmpl $0x0, -0x504(%rbp)
movb %al, -0x56c(%rbp)
jne 0x3876
movq -0x500(%rbp), %rax
movq %rax, -0x578(%rbp)
callq 0x23b0
movq -0x578(%rbp), %rdi
movl %eax, %esi
addl $0x44aa20, %esi         # imm = 0x44AA20
callq 0x1bc0
cmpl $0x0, %eax
setne %al
movb %al, -0x56c(%rbp)
movb -0x56c(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x504(%rbp)
movb $0x1, %al
cmpl $0x0, -0x504(%rbp)
movb %al, -0x579(%rbp)
jne 0x38c1
movq -0x500(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
movq -0x4f8(%rbp), %rax
movzwl %ax, %edx
callq 0x1bf0
cmpl $0x0, %eax
setne %al
movb %al, -0x579(%rbp)
movb -0x579(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x504(%rbp)
cmpl $0x0, -0x504(%rbp)
je 0x38ef
movl -0x504(%rbp), %esi
leaq 0xbf4(%rip), %rdi       # 0x44dc
movb $0x0, %al
callq 0x1db0
movl 0x3847(%rip), %edi      # 0x713c
movq -0x500(%rbp), %rsi
callq 0x2340
cmpl $-0x1, %eax
jne 0x3912
leaq 0xa2c(%rip), %rdi       # 0x4339
callq 0x1e60
movq 0x3c5f(%rip), %rdi      # 0x7578
movq -0x500(%rbp), %rsi
callq 0x28c0
cmpl $-0x1, %eax
jne 0x3938
leaq 0xbc8(%rip), %rdi       # 0x44f9
movb $0x0, %al
callq 0x1db0
movq 0x3c31(%rip), %rax      # 0x7570
addq $0x1, %rax
andq $0xff, %rax
movq %rax, 0x3c20(%rip)      # 0x7570
movq -0x500(%rbp), %rdi
callq 0x1f00
movq %rax, %rsi
leaq 0xbb3(%rip), %rdi       # 0x4519
movb $0x0, %al
callq 0x1ce0
movq -0x500(%rbp), %rdi
callq 0x19b0
movzbl %al, %esi
leaq 0xb9c(%rip), %rdi       # 0x451f
movb $0x0, %al
callq 0x1ce0
cmpq $0x0, -0x4f8(%rbp)
jne 0x39a9
leaq 0xba0(%rip), %rdi       # 0x453b
movb $0x0, %al
callq 0x1ce0
movb $0x1, 0x3bd7(%rip)      # 0x7580
jmp 0x39ab
addq $0x580, %rsp            # imm = 0x580
popq %rbp
retq
nopw %cs:(%rax,%rax)