// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
pushq %rax
movq %rdi, %rbx
cmpq $0x0, 0x48(%rdi)
je 0x1a7fc
callq 0x1f784
movq %rax, %rdi
callq 0x1fafc
cmpq 0x48(%rbx), %rax
jbe 0x1a807
xorl %r14d, %r14d
jmp 0x1aa6a
movl 0x150(%rbx), %eax
cmpl 0x50(%rbx), %eax
jae 0x1a7f4
pushq $0x28
popq %rdi
callq 0x7370
movq %rax, %r14
movq 0x480(%rbx), %rdi
movsd 0x2b2ff(%rip), %xmm1    # 0x45b20
xorpd %xmm0, %xmm0
callq 0x411f0
movsd 0x470(%rbx), %xmm1
ucomisd %xmm0, %xmm1
pushq $0x1
popq %rbp
jae 0x1a845
incl 0x158(%rbx)
movl %ebp, %eax
jmp 0x1a84d
incl 0x154(%rbx)
xorl %eax, %eax
movl %eax, 0x1c(%r14)
movl 0x4d8(%rbx), %eax
cmpl $0x1, %eax
je 0x1a86c
testl %eax, %eax
jne 0x1aa78
movl 0x4dc(%rbx), %ebp
jmp 0x1a89e
movq 0x4e8(%rbx), %rdi
movl 0x4dc(%rbx), %eax
movl 0x4e0(%rbx), %ecx
cvtsi2sd %rax, %xmm0
cvtsi2sd %rcx, %xmm1
callq 0x414b2
callq 0x7070
cvttsd2si %xmm0, %rax
cmpl $0x2, %eax
cmovael %eax, %ebp
movl %ebp, 0x18(%r14)
movl 0x48c(%rbx), %eax
cmpl $0x3, %eax
je 0x1a98d
cmpl $0x2, %eax
je 0x1a944
cmpl $0x1, %eax
jne 0x1aaa8
movq 0x4d0(%rbx), %r15
movq %r15, 0x10(%r14)
movl %ebp, %ecx
addq %r15, %rcx
cmpq 0x70(%rbx), %rcx
jbe 0x1a8eb
movq 0x68(%rbx), %r15
movq %r15, 0x10(%r14)
movq %rcx, 0x4d0(%rbx)
movq %r15, %rcx
movq %rcx, 0x4d0(%rbx)
cmpb $0x1, 0x514(%rbx)
jne 0x1a91b
movl 0x518(%rbx), %esi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
testq %rdx, %rdx
je 0x1a91b
subq %rdx, %rcx
addq %rsi, %rcx
movq %rcx, 0x4d0(%rbx)
cmpq %r15, %rcx
jne 0x1aa36
movq 0x4764d(%rip), %rdi     # 0x61f78
leaq 0x2b2ac(%rip), %rsi     # 0x45bde
callq 0x7360
movq %rax, %rdi
callq 0x71a0
jmp 0x1aa36
movq 0x498(%rbx), %rdi
movq 0x68(%rbx), %rsi
movq 0x70(%rbx), %rdx
callq 0x41280
movq %rax, 0x10(%r14)
movq 0x68(%rbx), %r15
cmpq %r15, %rax
jb 0x1aa11
movq 0x70(%rbx), %rcx
cmpq %rcx, %rax
ja 0x1aa11
movl %ebp, %edx
addq %rax, %rdx
cmpq %rcx, %rdx
jbe 0x1aa33
movq %r15, 0x10(%r14)
jmp 0x1aa36
movq 0x4a8(%rbx), %rdi
movsd 0x2b184(%rip), %xmm1    # 0x45b20
xorpd %xmm0, %xmm0
callq 0x411f0
movsd 0x490(%rbx), %xmm1
ucomisd %xmm0, %xmm1
movq 0x4b8(%rbx), %rdi
jbe 0x1a9eb
movq 0x4c8(%rbx), %rsi
incq %rsi
movq 0x70(%rbx), %rdx
callq 0x41280
movq %rax, %r15
movq %rax, 0x10(%r14)
movq 0x4c8(%rbx), %rax
incq %rax
cmpq %rax, %r15
jb 0x1aa11
cmpq 0x70(%rbx), %r15
jbe 0x1aa36
jmp 0x1aa11
movq 0x68(%rbx), %rsi
movq 0x4c8(%rbx), %rdx
callq 0x41280
movq %rax, 0x10(%r14)
cmpq 0x68(%rbx), %rax
jb 0x1aa11
movq %rax, %r15
cmpq 0x4c8(%rbx), %rax
jbe 0x1aa36
movq 0x475d8(%rip), %rbx     # 0x61ff0
leaq 0x29b69(%rip), %rsi     # 0x44588
movq %rbx, %rdi
callq 0x7360
leaq 0x2b212(%rip), %rsi     # 0x45c40
jmp 0x1aac5
movq %rax, %r15
cmpb $0x1, 0x514(%rbx)
jne 0x1aa54
movl 0x518(%rbx), %ecx
movq %r15, %rax
xorl %edx, %edx
divq %rcx
subq %rdx, %r15
movq %r15, 0x10(%r14)
incl 0x150(%rbx)
callq 0x1f784
movq %rax, %rdi
callq 0x1fafc
movq %rax, (%r14)
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x71b0
movq %rax, %rbx
leaq 0x2b129(%rip), %rsi     # 0x45bb3
movq %rax, %rdi
callq 0x7620
movq 0x4752f(%rip), %rsi     # 0x61fc8
movq 0x47508(%rip), %rdx     # 0x61fa8
movq %rbx, %rdi
callq 0x7590
movq 0x47541(%rip), %rbx     # 0x61ff0
leaq 0x29ad2(%rip), %rsi     # 0x44588
movq %rbx, %rdi
callq 0x7360
leaq 0x2b1b4(%rip), %rsi     # 0x45c79
movq %rbx, %rdi
callq 0x7360
movq %rax, %rdi
callq 0x71a0
movq 0x474f4(%rip), %rdi     # 0x61fd0
callq 0x73d0
pushq $0x1
popq %rdi
callq 0x73e0
movq %rax, %r14
movq %rbx, %rdi
callq 0x72a0
movq %r14, %rdi
callq 0x75d0