// File: /workspace/github_cpp_makefile_star2_O2/narges64[P]SIMBA/ssd.cpp
// Function: generate_next_request(ssd_info*, long)
request * generate_next_request(ssd_info * ssd, int64_t nearest_event_time){
	if (ssd->request_queue_length >= ssd->parameter->queue_length){
		return NULL;
	}

	static uint64_t previous_time = 0;
	double rd_ratio = ssd->parameter->syn_rd_ratio;
	int lun_number = ssd->parameter->lun_num;
	uint64_t min_sector_address = 0;
	uint64_t max_sector_address =(long int)(((long int)ssd->parameter->subpage_page*ssd->parameter->page_block*ssd->parameter->block_plane*ssd->parameter->plane_lun*ssd->parameter->lun_num)*(1-ssd->parameter->overprovide));

	uint64_t size = ssd->parameter->syn_req_size;
	uint64_t avg_time = ssd->parameter->syn_interarrival_mean; 
	int event_count = ssd->parameter->syn_req_count;

	// Time
 	uint64_t new_time = 0;
 	uint64_t time_interval = expo_dist(avg_time);//, 1);
 	new_time = previous_time  + time_interval;
	if (new_time < ssd->current_time) new_time = ssd->current_time;

	if (new_time > nearest_event_time)
		return NULL;

 	previous_time = new_time;
	request * request1 = new request();
	request1->app_id = 1;
	request1->io_num = ssd->request_sequence_number;
	request1->time = new_time;

 	// Operation
 	int r = rand() % 100;
 	if (r < (rd_ratio*100)) {
		request1->operation = 1; // Read
 	}else {
		request1->operation = 0; // Write
 	}

 	// Address
	int align = ssd->parameter->subpage_page; 
 	uint64_t address = (rand() % (max_sector_address - min_sector_address)) + min_sector_address ;
	request1->lsn = address;

 	// Size
 	int req_size = size;
	request1->size = size;

	if (request1->io_num > event_count) {
		request1->time = MAX_INT64;
	}else {
		ssd->request_sequence_number++;
	}
	return request1;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl 0x1c(%rdi), %ecx
movq 0x58(%rdi), %rax
cmpl 0x78(%rax), %ecx
jge 0x81a8
movq %rsi, %r14
movq %rdi, %rbx
movss 0x324(%rax), %xmm0
movss %xmm0, (%rsp)
movl 0x238(%rax), %ecx
movq %rcx, 0x18(%rsp)
movl 0x234(%rax), %r13d
movl 0x230(%rax), %ecx
movq %rcx, 0x20(%rsp)
movl 0x88(%rax), %r12d
movl 0x22c(%rax), %ebp
movss 0x25c(%rax), %xmm0
movss %xmm0, 0xc(%rsp)
movl 0x32c(%rax), %ecx
movl %ecx, 0x14(%rsp)
movslq 0x330(%rax), %rcx
movq %rcx, %xmm1
punpckldq 0x19e0(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x19e8(%rip), %xmm1     # 0x9b40
movl 0x328(%rax), %eax
movl %eax, 0x10(%rsp)
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x809e
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1991(%rip), %xmm0     # 0x9b18
cvttsd2si %xmm0, %r15
andq %rcx, %r15
orq %rax, %r15
addq 0x601f(%rip), %r15      # 0xe1b8
movq (%rbx), %rax
cmpq %rax, %r15
cmovbeq %rax, %r15
cmpq %r14, %r15
jbe 0x81bd
xorl %r14d, %r14d
movq %r14, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
imulq 0x18(%rsp), %r13
imulq 0x20(%rsp), %rbp
imulq %r13, %rbp
imulq %rbp, %r12
movss 0xe67(%rip), %xmm0      # 0x9040
subss 0xc(%rsp), %xmm0
cvtsi2ss %r12, %xmm1
mulss %xmm0, %xmm1
cvttss2si %xmm1, %r12
cvtss2sd (%rsp), %xmm0
movsd %xmm0, (%rsp)
movq %r15, 0x5fba(%rip)      # 0xe1b8
pushq $0x48
popq %rdi
callq 0x2160
movq %rax, %r14
xorps %xmm0, %xmm0
movups %xmm0, 0x1c(%rax)
movups %xmm0, 0x2c(%rax)
movups %xmm0, 0x38(%rax)
movl $0x1, (%rax)
movl 0x8(%rbx), %ebp
movl %ebp, 0x4(%rax)
movq %r15, 0x8(%rax)
callq 0x2090
pushq $0x64
popq %rcx
cltd
idivl %ecx
cvtsi2sd %edx, %xmm0
movsd (%rsp), %xmm1
mulsd 0x18dc(%rip), %xmm1     # 0x9b20
xorl %eax, %eax
ucomisd %xmm0, %xmm1
seta %al
movl %eax, 0x18(%r14)
callq 0x2090
cltq
xorl %edx, %edx
divq %r12
movl %edx, 0x10(%r14)
movl 0x14(%rsp), %eax
movl %eax, 0x14(%r14)
cmpl 0x10(%rsp), %ebp
jbe 0x8282
movabsq $0x7fffffffffffffff, %rax # imm = 0x7FFFFFFFFFFFFFFF
movq %rax, 0x8(%r14)
jmp 0x81ab
incl 0x8(%rbx)
jmp 0x81ab