// File: /workspace/github_c_makefile_star2_O0/OnionIoT[P]lv_example/lvgl/src/lv_misc/lv_task.c
// Function: lv_task_handler
LV_ATTRIBUTE_TASK_HANDLER void lv_task_handler(void)
{
    LV_LOG_TRACE("lv_task_handler started");

    /*Avoid concurrent running of the task handler*/
    static bool already_running = false;
    if(already_running) return;
    already_running = true;

    static uint32_t idle_period_start = 0;
    static uint32_t handler_start     = 0;
    static uint32_t busy_time         = 0;

    if(lv_task_run == false) {
        already_running = false; /*Release mutex*/
        return;
    }

    handler_start = lv_tick_get();

    /* Run all task from the highest to the lowest priority
     * If a lower priority task is executed check task again from the highest priority
     * but on the priority of executed tasks don't run tasks before the executed*/
    lv_task_t * task_interrupter = NULL;
    lv_task_t * next;
    bool end_flag;
    do {
        end_flag                 = true;
        task_deleted             = false;
        task_created             = false;
        LV_GC_ROOT(_lv_task_act) = lv_ll_get_head(&LV_GC_ROOT(_lv_task_ll));
        while(LV_GC_ROOT(_lv_task_act)) {
            /* The task might be deleted if it runs only once ('once = 1')
             * So get next element until the current is surely valid*/
            next = lv_ll_get_next(&LV_GC_ROOT(_lv_task_ll), LV_GC_ROOT(_lv_task_act));

            /*We reach priority of the turned off task. There is nothing more to do.*/
            if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_OFF) {
                break;
            }

            /*Here is the interrupter task. Don't execute it again.*/
            if(LV_GC_ROOT(_lv_task_act) == task_interrupter) {
                task_interrupter = NULL; /*From this point only task after the interrupter comes, so
                                            the interrupter is not interesting anymore*/
                LV_GC_ROOT(_lv_task_act) = next;
                continue; /*Load the next task*/
            }

            /*Just try to run the tasks with highest priority.*/
            if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio == LV_TASK_PRIO_HIGHEST) {
                lv_task_exec(LV_GC_ROOT(_lv_task_act));
            }
            /*Tasks with higher priority than the interrupted shall be run in every case*/
            else if(task_interrupter) {
                if(((lv_task_t *)LV_GC_ROOT(_lv_task_act))->prio > task_interrupter->prio) {
                    if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
                        if(!task_created && !task_deleted) {
                            /*Check all tasks again from the highest priority */
                            task_interrupter = LV_GC_ROOT(_lv_task_act);
                            end_flag = false;
                            break;
                        }
                    }
                }
            }
            /* It is no interrupter task or we already reached it earlier.
             * Just run the remaining tasks*/
            else {
                if(lv_task_exec(LV_GC_ROOT(_lv_task_act))) {
                    if(!task_created && !task_deleted) {
                        task_interrupter = LV_GC_ROOT(_lv_task_act); /*Check all tasks again from the highest priority */
                        end_flag         = false;
                        break;
                    }
                }
            }

            /*If a task was created or deleted then this or the next item might be corrupted*/
            if(task_created || task_deleted) {
                task_interrupter = NULL;
                break;
            }

            LV_GC_ROOT(_lv_task_act) = next; /*Load the next task*/
        }
    } while(!end_flag);

    busy_time += lv_tick_elaps(handler_start);
    uint32_t idle_period_time = lv_tick_elaps(idle_period_start);
    if(idle_period_time >= IDLE_MEAS_PERIOD) {

        idle_last         = (uint32_t)((uint32_t)busy_time * 100) / IDLE_MEAS_PERIOD; /*Calculate the busy percentage*/
        idle_last         = idle_last > 100 ? 0 : 100 - idle_last;                    /*But we need idle time*/
        busy_time         = 0;
        idle_period_start = lv_tick_get();
    }

    already_running = false; /*Release the mutex*/

    LV_LOG_TRACE("lv_task_handler ready");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
testb $0x1, 0x46969(%rip)     # 0x89578
je 0x42c16
jmp 0x42e88
movb $0x1, 0x4695b(%rip)     # 0x89578
movb 0x46965(%rip), %al      # 0x89588
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x42c39
movb $0x0, 0x46944(%rip)     # 0x89578
jmp 0x42e88
callq 0xdfe0
movl %eax, 0x4693c(%rip)     # 0x89580
movq $0x0, -0x8(%rbp)
movb $0x1, -0x11(%rbp)
movb $0x0, 0x46932(%rip)     # 0x89589
movb $0x0, 0x4692c(%rip)     # 0x8958a
leaq 0x4e94b(%rip), %rdi     # 0x915b0
callq 0x45660
movq %rax, %rcx
leaq 0x4ea04(%rip), %rax     # 0x91678
movq %rcx, (%rax)
leaq 0x4e9fa(%rip), %rax     # 0x91678
cmpq $0x0, (%rax)
je 0x42dec
leaq 0x4e9e9(%rip), %rax     # 0x91678
movq (%rax), %rsi
leaq 0x4e917(%rip), %rdi     # 0x915b0
callq 0x458a0
movq %rax, -0x10(%rbp)
leaq 0x4e9cf(%rip), %rax     # 0x91678
movq (%rax), %rax
movb 0x18(%rax), %al
andb $0x7, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x42cbe
jmp 0x42dec
leaq 0x4e9b3(%rip), %rax     # 0x91678
movq (%rax), %rax
cmpq -0x8(%rbp), %rax
jne 0x42ce6
movq $0x0, -0x8(%rbp)
movq -0x10(%rbp), %rcx
leaq 0x4e997(%rip), %rax     # 0x91678
movq %rcx, (%rax)
jmp 0x42c77
leaq 0x4e98b(%rip), %rax     # 0x91678
movq (%rax), %rax
movb 0x18(%rax), %al
andb $0x7, %al
movzbl %al, %eax
cmpl $0x5, %eax
jne 0x42d11
leaq 0x4e974(%rip), %rax     # 0x91678
movq (%rax), %rdi
callq 0x42e90
jmp 0x42dbd
cmpq $0x0, -0x8(%rbp)
je 0x42d7c
leaq 0x4e959(%rip), %rax     # 0x91678
movq (%rax), %rax
movb 0x18(%rax), %al
andb $0x7, %al
movzbl %al, %eax
movq -0x8(%rbp), %rcx
movb 0x18(%rcx), %cl
andb $0x7, %cl
movzbl %cl, %ecx
cmpl %ecx, %eax
jle 0x42d7a
leaq 0x4e936(%rip), %rax     # 0x91678
movq (%rax), %rdi
callq 0x42e90
testb $0x1, %al
jne 0x42d50
jmp 0x42d78
testb $0x1, 0x46833(%rip)     # 0x8958a
jne 0x42d76
testb $0x1, 0x46829(%rip)     # 0x89589
jne 0x42d76
leaq 0x4e90f(%rip), %rax     # 0x91678
movq (%rax), %rax
movq %rax, -0x8(%rbp)
movb $0x0, -0x11(%rbp)
jmp 0x42dec
jmp 0x42d78
jmp 0x42d7a
jmp 0x42dbb
leaq 0x4e8f5(%rip), %rax     # 0x91678
movq (%rax), %rdi
callq 0x42e90
testb $0x1, %al
jne 0x42d91
jmp 0x42db9
testb $0x1, 0x467f2(%rip)     # 0x8958a
jne 0x42db7
testb $0x1, 0x467e8(%rip)     # 0x89589
jne 0x42db7
leaq 0x4e8ce(%rip), %rax     # 0x91678
movq (%rax), %rax
movq %rax, -0x8(%rbp)
movb $0x0, -0x11(%rbp)
jmp 0x42dec
jmp 0x42db9
jmp 0x42dbb
jmp 0x42dbd
testb $0x1, 0x467c6(%rip)     # 0x8958a
jne 0x42dcf
testb $0x1, 0x467bc(%rip)     # 0x89589
je 0x42dd9
movq $0x0, -0x8(%rbp)
jmp 0x42dec
movq -0x10(%rbp), %rcx
leaq 0x4e894(%rip), %rax     # 0x91678
movq %rcx, (%rax)
jmp 0x42c77
jmp 0x42dee
movb -0x11(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x42c4c
movl 0x4677f(%rip), %edi     # 0x89580
callq 0xe010
addl 0x46778(%rip), %eax     # 0x89584
movl %eax, 0x46772(%rip)     # 0x89584
movl 0x46764(%rip), %edi     # 0x8957c
callq 0xe010
movl %eax, -0x18(%rbp)
cmpl $0x1f4, -0x18(%rbp)     # imm = 0x1F4
jb 0x42e81
imull $0x64, 0x46754(%rip), %eax # 0x89584
movl $0x1f4, %ecx            # imm = 0x1F4
xorl %edx, %edx
divl %ecx
movb %al, 0x4674c(%rip)      # 0x8958b
movzbl 0x46745(%rip), %eax     # 0x8958b
cmpl $0x64, %eax
jle 0x42e52
xorl %eax, %eax
movl %eax, -0x1c(%rbp)
jmp 0x42e63
movzbl 0x46732(%rip), %ecx     # 0x8958b
movl $0x64, %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movb %al, 0x4671f(%rip)      # 0x8958b
movl $0x0, 0x4670e(%rip)     # 0x89584
callq 0xdfe0
movl %eax, 0x466fb(%rip)     # 0x8957c
movb $0x0, 0x466f0(%rip)     # 0x89578
addq $0x20, %rsp
popq %rbp
retq
nop