// File: /workspace/github_c_makefile_star2_O1/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:
cmpb $0x0, 0x37cf2(%rip)     # 0x604a8
jne 0x2892d
movb $0x1, 0x37ce5(%rip)     # 0x604a8
cmpb $0x0, 0x37cee(%rip)     # 0x604b8
je 0x28926
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
callq 0x883e
movl %eax, 0x37ccc(%rip)     # 0x604b0
xorl %r12d, %r12d
leaq 0x3fcf2(%rip), %rbx     # 0x684e0
leaq 0x3fdb3(%rip), %r15     # 0x685a8
xorl %r13d, %r13d
movb %r13b, 0x37cba(%rip)    # 0x604b9
movb %r13b, 0x37cb4(%rip)    # 0x604ba
movq %rbx, %rdi
callq 0x29cce
movq %rax, (%r15)
testq %rax, %rax
je 0x288af
movq %rax, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x29dfb
movq %rax, %r14
movq (%r15), %rdi
movb 0x18(%rdi), %al
andb $0x7, %al
je 0x288a4
cmpq %r12, %rdi
je 0x2888d
cmpb $0x5, %al
jne 0x28845
callq 0x2892e
jmp 0x28871
testq %r12, %r12
je 0x28856
movb 0x18(%r12), %cl
andb $0x7, %cl
cmpb %cl, %al
jbe 0x28871
callq 0x2892e
testb %al, %al
je 0x28871
cmpb $0x0, 0x37c54(%rip)     # 0x604ba
jne 0x28871
cmpb $0x0, 0x37c4a(%rip)     # 0x604b9
je 0x288ba
cmpb $0x0, 0x37c42(%rip)     # 0x604ba
jne 0x288a9
cmpb $0x0, 0x37c38(%rip)     # 0x604b9
jne 0x288a9
movq %r14, (%r15)
testq %r14, %r14
jne 0x2881d
jmp 0x288a4
movq %r14, (%r15)
xorl %r12d, %r12d
movl $0x0, %r13d
testq %r14, %r14
jne 0x2881d
jmp 0x288af
xorl %r13d, %r13d
jmp 0x288af
xorl %r13d, %r13d
xorl %r12d, %r12d
testb %r13b, %r13b
jne 0x287f5
jmp 0x288c2
movq (%r15), %r12
movb $0x1, %r13b
jmp 0x288af
movl 0x37be8(%rip), %edi     # 0x604b0
callq 0x8855
addl %eax, 0x37be1(%rip)     # 0x604b4
movl 0x37bd3(%rip), %edi     # 0x604ac
callq 0x8855
cmpl $0x1f4, %eax            # imm = 0x1F4
jb 0x2891d
imull $0x64, 0x37bc8(%rip), %eax # 0x604b4
imulq $0x10624dd3, %rax, %rax # imm = 0x10624DD3
shrq $0x25, %rax
movzbl %al, %eax
xorl %ecx, %ecx
movl $0x64, %edx
subl %eax, %edx
cmovbl %ecx, %edx
movb %dl, 0x37baf(%rip)      # 0x604bb
movl %ecx, 0x37ba2(%rip)     # 0x604b4
callq 0x883e
movl %eax, 0x37b8f(%rip)     # 0x604ac
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
movb $0x0, 0x37b7b(%rip)     # 0x604a8
retq