// File: /workspace/github_c_makefile_star2_O0/wtarreau[P]httpterm/httpterm.c
// Function: task_queue
struct task *task_queue(struct task *task) {
    struct task *list = task->wq;
    struct task *start_from;

    /* This is a very dirty hack to queue non-expirable tasks in another queue
     * in order to avoid pulluting the tail of the standard queue. This will go
     * away with the new O(log(n)) scheduler anyway.
     */
    if (tv_iseternity(&task->expire)) {
	/* if the task was queued in the standard wait queue, we must dequeue it */
	if (task->prev) {
	    if (task->wq == LIST_HEAD(wait_queue[1]))
		return task;
	    else {
		task_delete(task);
		task->prev = NULL;
	    }
	}
	list = task->wq = LIST_HEAD(wait_queue[1]);
    } else {
	/* if the task was queued in the eternity queue, we must dequeue it */
	if (task->prev && (task->wq == LIST_HEAD(wait_queue[1]))) {
	    task_delete(task);
	    task->prev = NULL;
	    list = task->wq = LIST_HEAD(wait_queue[0]);
	}
    }

    /* next, test if the task was already in a list */
    if (task->prev == NULL) {
	//	start_from = list;
	start_from = list->prev;
	/* insert the unlinked <task> into the list, searching back from the last entry */
	while (start_from != list && tv_cmp2(&task->expire, &start_from->expire) < 0) {
	    start_from = start_from->prev;
	}
	
	//	  while (start_from->next != list && tv_cmp2(&task->expire, &start_from->next->expire) > 0) {
	//	      start_from = start_from->next;
	//	      stats_tsk_nsrch++;
	//	  }
    }	
    else if (task->prev == list ||
	     tv_cmp2(&task->expire, &task->prev->expire) >= 0) { /* walk right */
	start_from = task->next;
	if (start_from == list || tv_cmp2(&task->expire, &start_from->expire) <= 0) {
	    return task; /* it's already in the right place */
	}

	/* if the task is not at the right place, there's little chance that
	 * it has only shifted a bit, and it will nearly always be queued
	 * at the end of the list because of constant timeouts
	 * (observed in real case).
	 */
#ifndef WE_REALLY_THINK_THAT_THIS_TASK_MAY_HAVE_SHIFTED
	start_from = list->prev; /* assume we'll queue to the end of the list */
	while (start_from != list && tv_cmp2(&task->expire, &start_from->expire) < 0) {
	    start_from = start_from->prev;
	}
#else /* WE_REALLY_... */
	/* insert the unlinked <task> into the list, searching after position <start_from> */
	while (start_from->next != list && tv_cmp2(&task->expire, &start_from->next->expire) > 0) {
	    start_from = start_from->next;
	}
#endif /* WE_REALLY_... */

	/* we need to unlink it now */
	task_delete(task);
    }
    else { /* walk left. */
#ifdef LEFT_TO_TOP	/* not very good */
	start_from = list;
	while (start_from->next != list && tv_cmp2(&task->expire, &start_from->next->expire) > 0) {
	    start_from = start_from->next;
	}
#else
	start_from = task->prev->prev; /* valid because of the previous test above */
	while (start_from != list && tv_cmp2(&task->expire, &start_from->expire) < 0) {
	    start_from = start_from->prev;
	}
#endif
	/* we need to unlink it now */
	task_delete(task);
    }
    task->prev = start_from;
    task->next = start_from->next;
    task->next->prev = task;
    start_from->next = task;
    return task;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
callq 0x3b20
cmpl $0x0, %eax
je 0x3902
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x38de
movq -0x10(%rbp), %rax
leaq 0xd9b0(%rip), %rcx      # 0x11260
addq $0x48, %rcx
cmpq %rcx, 0x18(%rax)
jne 0x38c7
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x3b15
movq -0x10(%rbp), %rdi
callq 0x3b60
movq -0x10(%rbp), %rax
movq $0x0, 0x8(%rax)
jmp 0x38de
movq -0x10(%rbp), %rax
leaq 0xd977(%rip), %rcx      # 0x11260
addq $0x48, %rcx
movq %rcx, 0x18(%rax)
leaq 0xd968(%rip), %rax      # 0x11260
addq $0x48, %rax
movq %rax, -0x18(%rbp)
jmp 0x3953
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x3951
movq -0x10(%rbp), %rax
leaq 0xd948(%rip), %rcx      # 0x11260
addq $0x48, %rcx
cmpq %rcx, 0x18(%rax)
jne 0x3951
movq -0x10(%rbp), %rdi
callq 0x3b60
movq -0x10(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
leaq 0xd91e(%rip), %rcx      # 0x11260
movq %rcx, 0x18(%rax)
leaq 0xd913(%rip), %rax      # 0x11260
movq %rax, -0x18(%rbp)
jmp 0x3953
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x39b3
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x21(%rbp)
je 0x3997
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x20(%rbp), %rsi
addq $0x28, %rsi
callq 0x3ba0
cmpl $0x0, %eax
setl %al
movb %al, -0x21(%rbp)
movb -0x21(%rbp), %al
testb $0x1, %al
jne 0x39a0
jmp 0x39ae
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x396a
jmp 0x3ad9
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
cmpq -0x18(%rbp), %rax
je 0x39e3
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0x28, %rsi
callq 0x3ba0
cmpl $0x0, %eax
jl 0x3a7a
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x18(%rbp), %rax
je 0x3a12
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x20(%rbp), %rsi
addq $0x28, %rsi
callq 0x3ba0
cmpl $0x0, %eax
jg 0x3a1f
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x3b15
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x22(%rbp)
je 0x3a58
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x20(%rbp), %rsi
addq $0x28, %rsi
callq 0x3ba0
cmpl $0x0, %eax
setl %al
movb %al, -0x22(%rbp)
movb -0x22(%rbp), %al
testb $0x1, %al
jne 0x3a61
jmp 0x3a6f
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x3a2b
movq -0x10(%rbp), %rdi
callq 0x3b60
jmp 0x3ad7
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x23(%rbp)
je 0x3ab7
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x20(%rbp), %rsi
addq $0x28, %rsi
callq 0x3ba0
cmpl $0x0, %eax
setl %al
movb %al, -0x23(%rbp)
movb -0x23(%rbp), %al
testb $0x1, %al
jne 0x3ac0
jmp 0x3ace
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x3a8a
movq -0x10(%rbp), %rdi
callq 0x3b60
jmp 0x3ad9
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq (%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rcx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x30, %rsp
popq %rbp
retq
nop