// File: /workspace/github_cpp_makefile_star2_O1/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 %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
cmpq $0x0, 0x48(%rdi)
je 0x2239a
callq 0x281b4
movq %rax, %rdi
callq 0x285a6
cmpq 0x48(%rbx), %rax
jbe 0x223a5
xorl %r14d, %r14d
jmp 0x2262e
movl 0x150(%rbx), %eax
cmpl 0x50(%rbx), %eax
jae 0x22392
movl $0x28, %edi
callq 0x73a0
movq %rax, %r14
movq 0x480(%rbx), %rdi
movsd 0x3584f(%rip), %xmm1    # 0x57c10
xorpd %xmm0, %xmm0
callq 0x53bfa
movsd 0x470(%rbx), %xmm1
ucomisd %xmm0, %xmm1
jae 0x223e8
movl $0x1, 0x1c(%r14)
incl 0x158(%rbx)
jmp 0x223f6
movl $0x0, 0x1c(%r14)
incl 0x154(%rbx)
movl 0x4d8(%rbx), %eax
cmpl $0x1, %eax
je 0x22415
testl %eax, %eax
jne 0x22656
movl 0x4dc(%rbx), %eax
movl %eax, 0x18(%r14)
jmp 0x22456
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 0x53ed8
callq 0x7090
cvttsd2si %xmm0, %rax
cmpl $0x2, %eax
movl $0x1, %ecx
cmovael %eax, %ecx
movl %ecx, 0x18(%r14)
movl 0x48c(%rbx), %eax
cmpl $0x3, %eax
je 0x22578
cmpl $0x2, %eax
je 0x22530
cmpl $0x1, %eax
jne 0x22688
movq 0x4d0(%rbx), %rcx
movq %rcx, 0x10(%r14)
movl 0x18(%r14), %eax
addq %rcx, %rax
cmpq 0x70(%rbx), %rax
jbe 0x224a1
movq 0x68(%rbx), %rcx
movq %rcx, 0x10(%r14)
movq %rax, 0x4d0(%rbx)
movq %rcx, %rax
movq %rax, 0x4d0(%rbx)
cmpb $0x1, 0x514(%rbx)
jne 0x224d8
movq 0x4d0(%rbx), %rcx
movl 0x518(%rbx), %esi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
testq %rdx, %rdx
je 0x224d8
subq %rdx, %rcx
addq %rsi, %rcx
movq %rcx, 0x4d0(%rbx)
movq 0x4d0(%rbx), %rax
cmpq 0x10(%r14), %rax
jne 0x225f6
movq 0x4caa0(%rip), %r15     # 0x6ef90
leaq 0x357d7(%rip), %rsi     # 0x57cce
movl $0x61, %edx
movq %r15, %rdi
callq 0x7400
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x7380
movsbl %al, %esi
movq %r15, %rdi
callq 0x7040
movq %rax, %rdi
callq 0x7290
jmp 0x225f6
movq 0x498(%rbx), %rdi
movq 0x68(%rbx), %rsi
movq 0x70(%rbx), %rdx
callq 0x53c96
movq %rax, 0x10(%r14)
movq 0x68(%rbx), %rcx
cmpq %rcx, %rax
jb 0x22637
movq 0x70(%rbx), %rdx
cmpq %rdx, %rax
ja 0x22637
movl 0x18(%r14), %esi
addq %rsi, %rax
cmpq %rdx, %rax
jbe 0x225f6
movq %rcx, 0x10(%r14)
jmp 0x225f6
movq 0x4a8(%rbx), %rdi
movsd 0x35689(%rip), %xmm1    # 0x57c10
xorpd %xmm0, %xmm0
callq 0x53bfa
movsd 0x490(%rbx), %xmm1
ucomisd %xmm0, %xmm1
movq 0x4b8(%rbx), %rdi
jbe 0x225d3
movq 0x4c8(%rbx), %rsi
incq %rsi
movq 0x70(%rbx), %rdx
callq 0x53c96
movq %rax, 0x10(%r14)
movq 0x4c8(%rbx), %rcx
incq %rcx
cmpq %rcx, %rax
jb 0x22637
cmpq 0x70(%rbx), %rax
jbe 0x225f6
jmp 0x22637
movq 0x68(%rbx), %rsi
movq 0x4c8(%rbx), %rdx
callq 0x53c96
movq %rax, 0x10(%r14)
cmpq 0x68(%rbx), %rax
jb 0x22637
cmpq 0x4c8(%rbx), %rax
ja 0x22637
cmpb $0x1, 0x514(%rbx)
jne 0x22618
movq 0x10(%r14), %rcx
movl 0x518(%rbx), %esi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
subq %rdx, %rcx
movq %rcx, 0x10(%r14)
incl 0x150(%rbx)
callq 0x281b4
movq %rax, %rdi
callq 0x285a6
movq %rax, (%r14)
movq %r14, %rax
popq %rbx
popq %r14
popq %r15
retq
movq 0x4c9b2(%rip), %rbx     # 0x6eff0
leaq 0x33f63(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x356dc(%rip), %rsi     # 0x57d30
jmp 0x226a5
movl $0x10, %edi
callq 0x71d0
movq %rax, %rbx
leaq 0x35639(%rip), %rsi     # 0x57ca3
movq %rax, %rdi
callq 0x7680
movq 0x4c94f(%rip), %rsi     # 0x6efc8
movq 0x4c930(%rip), %rdx     # 0x6efb0
movq %rbx, %rdi
callq 0x75e0
movq 0x4c961(%rip), %rbx     # 0x6eff0
leaq 0x33f12(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x356c4(%rip), %rsi     # 0x57d69
movq %rbx, %rdi
callq 0x7390
movq %rax, %rdi
callq 0x71c0
movq 0x4c914(%rip), %rdi     # 0x6efd0
callq 0x7430
movl $0x1, %edi
callq 0x7440
movq %rax, %r14
movq %rbx, %rdi
callq 0x72c0
movq %r14, %rdi
callq 0x7620