// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]MQSim/src/host/IO_Flow_Synthetic.cpp
// Function: Host_Components::IO_Flow_Synthetic::Generate_next_request()
Host_IO_Request* IO_Flow_Synthetic::Generate_next_request()
	{
		if (stop_time > 0) {
			if (Simulator->Time() > stop_time) {
				return NULL;
			}
		} else if (STAT_generated_request_count >= total_requests_to_be_generated) {
			return NULL;
		}
		
		Host_IO_Request* request = new Host_IO_Request;
		if (random_request_type_generator->Uniform(0, 1) <= read_ratio) {
			request->Type = Host_IO_Request_Type::READ;
			STAT_generated_read_request_count++;
		} else {
			request->Type = Host_IO_Request_Type::WRITE;
			STAT_generated_write_request_count++;
		}

		switch (request_size_distribution) {
			case Utils::Request_Size_Distribution_Type::FIXED:
				request->LBA_count = average_request_size;
				break;
			case Utils::Request_Size_Distribution_Type::NORMAL:
			{
				double temp_request_size = random_request_size_generator->Normal(average_request_size, variance_request_size);
				request->LBA_count = (unsigned int)(ceil(temp_request_size));
				if (request->LBA_count <= 0) {
					request->LBA_count = 1;
				}
				break;
			}
			default:
				throw std::invalid_argument("Uknown distribution type for requset size.");
		}

		switch (address_distribution) {
			case Utils::Address_Distribution_Type::STREAMING:
				request->Start_LBA = streaming_next_address;
				if (request->Start_LBA + request->LBA_count > end_lsa_on_device) {
					request->Start_LBA = start_lsa_on_device;
				}
				streaming_next_address += request->LBA_count;
				if (streaming_next_address > end_lsa_on_device) {
					streaming_next_address = start_lsa_on_device;
				}
				if (generate_aligned_addresses) {
					if(streaming_next_address % alignment_value != 0) {
						streaming_next_address += alignment_value - (streaming_next_address % alignment_value);
					}
				}
				if(streaming_next_address == request->Start_LBA) {
					PRINT_MESSAGE("Synthetic Message Generator: The same address is always repeated due to configuration parameters!")
				}
				break;
			case Utils::Address_Distribution_Type::RANDOM_HOTCOLD:
				// (100-hot)% of requests going to hot% of the address space
				if (random_hot_cold_generator->Uniform(0, 1) < hot_region_ratio) {
					request->Start_LBA = random_hot_address_generator->Uniform_ulong(hot_region_end_lsa + 1, end_lsa_on_device);
					if (request->Start_LBA < hot_region_end_lsa + 1 || request->Start_LBA > end_lsa_on_device) {
						PRINT_ERROR("Out of range address is generated in IO_Flow_Synthetic!\n")
						if (request->Start_LBA + request->LBA_count > end_lsa_on_device) {
							request->Start_LBA = hot_region_end_lsa + 1;
						}
					}
				} else {
					request->Start_LBA = random_hot_address_generator->Uniform_ulong(start_lsa_on_device, hot_region_end_lsa);
					if (request->Start_LBA < start_lsa_on_device || request->Start_LBA > hot_region_end_lsa) {
						PRINT_ERROR("Out of range address is generated in IO_Flow_Synthetic!\n")
					}
				}
				break;
			case Utils::Address_Distribution_Type::RANDOM_UNIFORM:
				request->Start_LBA = random_address_generator->Uniform_ulong(start_lsa_on_device, end_lsa_on_device);
				if (request->Start_LBA < start_lsa_on_device || request->Start_LBA > end_lsa_on_device) {
					PRINT_ERROR("Out of range address is generated in IO_Flow_Synthetic!\n")
				}
				if (request->Start_LBA + request->LBA_count > end_lsa_on_device) {
					request->Start_LBA = start_lsa_on_device;
				}
				break;
			default:
				PRINT_ERROR("Unknown address distribution type!\n")
		}

		if (generate_aligned_addresses) {
			request->Start_LBA -= request->Start_LBA % alignment_value;
		}
		STAT_generated_request_count++;
		request->Arrival_time = Simulator->Time();
		DEBUG("* Host: Request generated - " << (request->Type == Host_IO_Request_Type::READ ? "Read, " : "Write, ") << "LBA:" << request->Start_LBA << ", Size_in_bytes:" << request->LBA_count << "")

		return request;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdi, %rbx
cmpq $0x0, 0x48(%rdi)
je 0x22293
callq 0x28018
movq %rax, %rdi
callq 0x2841a
cmpq 0x48(%rbx), %rax
jbe 0x2229e
xorl %r14d, %r14d
jmp 0x22536
movl 0x150(%rbx), %eax
cmpl 0x50(%rbx), %eax
jae 0x2228b
movl $0x28, %edi
callq 0x73a0
movq %rax, %r14
movq 0x480(%rbx), %rdi
movsd 0x35956(%rip), %xmm1    # 0x57c10
xorpd %xmm0, %xmm0
callq 0x5329e
movsd 0x470(%rbx), %xmm1
ucomisd %xmm0, %xmm1
jae 0x222de
incl 0x158(%rbx)
movl $0x1, %eax
jmp 0x222e6
incl 0x154(%rbx)
xorl %eax, %eax
movl %eax, 0x1c(%r14)
movl 0x4d8(%rbx), %eax
cmpl $0x1, %eax
je 0x22305
testl %eax, %eax
jne 0x22542
movl 0x4dc(%rbx), %ebp
jmp 0x22342
movq 0x4e8(%rbx), %rdi
movl 0x4dc(%rbx), %eax
movl 0x4e0(%rbx), %ecx
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %rcx, %xmm1
callq 0x5357c
callq 0x7090
cvttsd2si %xmm0, %rax
cmpl $0x2, %eax
movl $0x1, %ebp
cmovael %eax, %ebp
movl %ebp, 0x18(%r14)
movl 0x48c(%rbx), %eax
cmpl $0x3, %eax
je 0x22459
cmpl $0x2, %eax
je 0x22410
cmpl $0x1, %eax
jne 0x22574
movq 0x4d0(%rbx), %r15
movq %r15, 0x10(%r14)
movl %ebp, %ecx
addq %r15, %rcx
cmpq 0x70(%rbx), %rcx
jbe 0x2238f
movq 0x68(%rbx), %r15
movq %r15, 0x10(%r14)
movq %rcx, 0x4d0(%rbx)
movq %r15, %rcx
movq %rcx, 0x4d0(%rbx)
cmpb $0x1, 0x514(%rbx)
jne 0x223bf
movl 0x518(%rbx), %esi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
testq %rdx, %rdx
je 0x223bf
subq %rdx, %rcx
addq %rsi, %rcx
movq %rcx, 0x4d0(%rbx)
cmpq %r15, %rcx
jne 0x22502
movq 0x4cbb9(%rip), %r12     # 0x6ef88
leaq 0x358f8(%rip), %rsi     # 0x57cce
movl $0x61, %edx
movq %r12, %rdi
callq 0x7400
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x7380
movsbl %al, %esi
movq %r12, %rdi
callq 0x7040
movq %rax, %rdi
callq 0x7290
jmp 0x22502
movq 0x498(%rbx), %rdi
movq 0x68(%rbx), %rsi
movq 0x70(%rbx), %rdx
callq 0x5333a
movq %rax, 0x10(%r14)
movq 0x68(%rbx), %r15
cmpq %r15, %rax
jb 0x224dd
movq 0x70(%rbx), %rcx
cmpq %rcx, %rax
ja 0x224dd
movl %ebp, %edx
addq %rax, %rdx
cmpq %rcx, %rdx
jbe 0x224ff
movq %r15, 0x10(%r14)
jmp 0x22502
movq 0x4a8(%rbx), %rdi
movsd 0x357a8(%rip), %xmm1    # 0x57c10
xorpd %xmm0, %xmm0
callq 0x5329e
movsd 0x490(%rbx), %xmm1
ucomisd %xmm0, %xmm1
movq 0x4b8(%rbx), %rdi
jbe 0x224b7
movq 0x4c8(%rbx), %rsi
incq %rsi
movq 0x70(%rbx), %rdx
callq 0x5333a
movq %rax, %r15
movq %rax, 0x10(%r14)
movq 0x4c8(%rbx), %rax
incq %rax
cmpq %rax, %r15
jb 0x224dd
cmpq 0x70(%rbx), %r15
jbe 0x22502
jmp 0x224dd
movq 0x68(%rbx), %rsi
movq 0x4c8(%rbx), %rdx
callq 0x5333a
movq %rax, 0x10(%r14)
cmpq 0x68(%rbx), %rax
jb 0x224dd
movq %rax, %r15
cmpq 0x4c8(%rbx), %rax
jbe 0x22502
movq 0x4cb0c(%rip), %rbx     # 0x6eff0
leaq 0x340bd(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x35836(%rip), %rsi     # 0x57d30
jmp 0x22591
movq %rax, %r15
cmpb $0x1, 0x514(%rbx)
jne 0x22520
movl 0x518(%rbx), %ecx
movq %r15, %rax
xorl %edx, %edx
divq %rcx
subq %rdx, %r15
movq %r15, 0x10(%r14)
incl 0x150(%rbx)
callq 0x28018
movq %rax, %rdi
callq 0x2841a
movq %rax, (%r14)
movq %r14, %rax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x71d0
movq %rax, %rbx
leaq 0x3574d(%rip), %rsi     # 0x57ca3
movq %rax, %rdi
callq 0x7680
movq 0x4ca63(%rip), %rsi     # 0x6efc8
movq 0x4ca3c(%rip), %rdx     # 0x6efa8
movq %rbx, %rdi
callq 0x75e0
movq 0x4ca75(%rip), %rbx     # 0x6eff0
leaq 0x34026(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x357d8(%rip), %rsi     # 0x57d69
movq %rbx, %rdi
callq 0x7390
movq %rax, %rdi
callq 0x71c0
movq 0x4ca28(%rip), %rdi     # 0x6efd0
callq 0x7430
movl $0x1, %edi
callq 0x7440
movq %rax, %r14
movq %rbx, %rdi
callq 0x72c0
movq %r14, %rdi
callq 0x7620