// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]MQSim/src/ssd/TSU_Priority_OutOfOrder.cpp
// Function: SSD_Components::TSU_Priority_OutOfOrder::get_next_read_service_queue(NVM::FlashMemory::Flash_Chip*)
Flash_Transaction_Queue *TSU_Priority_OutOfOrder::get_next_read_service_queue(NVM::FlashMemory::Flash_Chip *chip)
{
    if (UserReadTRQueue[chip->ChannelID][chip->ChipID][IO_Flow_Priority_Class::URGENT].size() > 0)
    {
        return &UserReadTRQueue[chip->ChannelID][chip->ChipID][IO_Flow_Priority_Class::URGENT];
    }

    int numberOfTries = 0;
    while(numberOfTries < IO_Flow_Priority_Class::get_scheduling_weight(IO_Flow_Priority_Class::HIGH))
    {
        nextPriorityClassRead[chip->ChannelID][chip->ChipID] = IO_Flow_Priority_Class::to_priority((nextPriorityClassRead[chip->ChannelID][chip->ChipID] + 1) % IO_Flow_Priority_Class::NUMBER_OF_PRIORITY_LEVELS);
        if (nextPriorityClassRead[chip->ChannelID][chip->ChipID] == IO_Flow_Priority_Class::URGENT)
        {
            nextPriorityClassRead[chip->ChannelID][chip->ChipID] = IO_Flow_Priority_Class::HIGH;
        }
        if (nextPriorityClassRead[chip->ChannelID][chip->ChipID] == IO_Flow_Priority_Class::HIGH)
        {
            numberOfTries++;
            currentWeightRead[chip->ChannelID][chip->ChipID]--;
            if (currentWeightRead[chip->ChannelID][chip->ChipID] <= 0)
            {
                currentWeightRead[chip->ChannelID][chip->ChipID] = IO_Flow_Priority_Class::get_scheduling_weight(IO_Flow_Priority_Class::HIGH);
            }
        }
        if (IO_Flow_Priority_Class::get_scheduling_weight(nextPriorityClassRead[chip->ChannelID][chip->ChipID]) >= currentWeightRead[chip->ChannelID][chip->ChipID]
            && UserReadTRQueue[chip->ChannelID][chip->ChipID][nextPriorityClassRead[chip->ChannelID][chip->ChipID]].size() > 0)
        {
            return &UserReadTRQueue[chip->ChannelID][chip->ChipID][nextPriorityClassRead[chip->ChannelID][chip->ChipID]];
        }
    }

    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq 0xb0(%rdi), %rax
movl 0x2c(%rsi), %edx
movl 0x30(%rsi), %ecx
movq (%rax,%rdx,8), %rax
movq (%rax,%rcx,8), %r15
cmpq $0x0, 0x18(%r15)
je 0x3f58c
movq %r15, %rax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rsi, %rbx
movq %rdi, %r14
xorl %r15d, %r15d
pushq $0x4
popq %rbp
xorl %r12d, %r12d
cmpl $0x3, %r12d
jg 0x3f580
movq 0xe8(%r14), %rax
movl %edx, %edx
movq (%rax,%rdx,8), %rax
movl %ecx, %ecx
movl (%rax,%rcx,4), %eax
incl %eax
cltd
idivl %ebp
movl %edx, %edi
callq 0x3fb82
movq 0xe8(%r14), %rcx
movl 0x2c(%rbx), %esi
movl 0x30(%rbx), %edx
movq (%rcx,%rsi,8), %rdi
movl %eax, (%rdi,%rdx,4)
cmpl $0x1, %eax
je 0x3f5e3
testl %eax, %eax
jne 0x3f611
movl $0x1, (%rdi,%rdx,4)
incl %r12d
movq 0xf8(%r14), %rax
movq (%rax,%rsi,8), %rsi
decl (%rsi,%rdx,4)
movl 0x2c(%rbx), %esi
movl 0x30(%rbx), %edx
movq (%rax,%rsi,8), %rax
cmpl $0x0, (%rax,%rdx,4)
jg 0x3f611
movl $0x4, (%rax,%rdx,4)
movl 0x2c(%rbx), %esi
movl 0x30(%rbx), %edx
movq (%rcx,%rsi,8), %rax
movl (%rax,%rdx,4), %edi
callq 0x3fb6e
movq 0xf8(%r14), %rsi
movl 0x2c(%rbx), %edx
movl 0x30(%rbx), %ecx
movq (%rsi,%rdx,8), %rsi
cmpl (%rsi,%rcx,4), %eax
jl 0x3f59b
movq 0xb0(%r14), %rax
movq 0xe8(%r14), %rsi
movq (%rax,%rdx,8), %rax
movq (%rax,%rcx,8), %rax
movq (%rsi,%rdx,8), %rsi
movl (%rsi,%rcx,4), %esi
imulq $0x108, %rsi, %rsi      # imm = 0x108
cmpq $0x0, 0x18(%rax,%rsi)
je 0x3f59b
addq %rsi, %rax
movq %rax, %r15
jmp 0x3f580