// File: /workspace/github_c_makefile_star2_O2/TeaInside[P]teavpn/src/third_party/thpool/thpool.c
// Function: thpool_init
struct thpool_* thpool_init(int num_threads){

	threads_on_hold   = 0;
	threads_keepalive = 1;

	if (num_threads < 0){
		num_threads = 0;
	}

	/* Make new thread pool */
	thpool_* thpool_p;
	thpool_p = (struct thpool_*)malloc(sizeof(struct thpool_));
	if (thpool_p == NULL){
		err("thpool_init(): Could not allocate memory for thread pool\n");
		return NULL;
	}
	thpool_p->num_threads_alive   = 0;
	thpool_p->num_threads_working = 0;

	/* Initialise the job queue */
	if (jobqueue_init(&thpool_p->__jobqueue) == -1){
		err("thpool_init(): Could not allocate memory for job queue\n");
		free(thpool_p);
		return NULL;
	}

	/* Make threads in pool */
	thpool_p->threads = (struct thread**)malloc(num_threads * sizeof(struct thread *));
	if (thpool_p->threads == NULL){
		err("thpool_init(): Could not allocate memory for threads\n");
		jobqueue_destroy(&thpool_p->__jobqueue);
		free(thpool_p);
		return NULL;
	}

	pthread_mutex_init(&(thpool_p->thcount_lock), NULL);
	pthread_cond_init(&thpool_p->threads_all_idle, NULL);

	/* Thread init */
	int n;
	for (n=0; n<num_threads; n++){
		thread_init(thpool_p, &thpool_p->threads[n], n);
#if THPOOL_DEBUG
			printf("THPOOL_DEBUG: Created thread %d in pool \n", n);
#endif
	}

	/* Wait for threads to initialize */
	while (thpool_p->num_threads_alive != num_threads) {}

	return thpool_p;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edi, %r14d
xorl %r15d, %r15d
movl %r15d, 0x5739(%rip)     # 0xb428
movl $0x1, 0x5733(%rip)      # 0xb42c
testl %edi, %edi
cmovlel %r15d, %r14d
movl $0xb0, %edi
callq 0x22c0
testq %rax, %rax
je 0x5df4
movq %rax, %rbx
movl %r15d, 0x8(%rax)
movl %r15d, 0xc(%rax)
andl $0x0, 0xa8(%rax)
pushq $0x60
popq %rdi
callq 0x22c0
xorps %xmm0, %xmm0
movups %xmm0, 0x90(%rbx)
movq %rax, 0xa0(%rbx)
testq %rax, %rax
je 0x5e12
leaq 0x68(%rbx), %r15
movq %r15, %rdi
xorl %esi, %esi
callq 0x23d0
movq 0xa0(%rbx), %rdi
callq 0x6394
movl %r14d, %r13d
leaq (,%r13,8), %rdi
callq 0x22c0
movq %rax, (%rbx)
testq %rax, %rax
je 0x5e30
leaq 0x10(%rbx), %rdi
xorl %r15d, %r15d
xorl %esi, %esi
callq 0x23d0
movq %rbx, %rdi
addq $0x38, %rdi
xorl %esi, %esi
callq 0x22a0
cmpq %r15, %r13
je 0x5dda
movq (%rbx), %r12
pushq $0x18
popq %rdi
callq 0x22c0
movq %rax, (%r12,%r15,8)
movq %rbx, 0x10(%rax)
movl %r15d, (%rax)
leaq 0x8(%rax), %rdi
xorl %esi, %esi
leaq 0x344(%rip), %rdx       # 0x6104
movq %rax, %rcx
callq 0x2310
movq (%r12,%r15,8), %rax
movq 0x8(%rax), %rdi
callq 0x22e0
incq %r15
jmp 0x5d98
movl 0x8(%rbx), %eax
cmpl %r14d, %eax
jne 0x5dda
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x51fd(%rip), %rax      # 0xaff8
movq (%rax), %rcx
leaq 0x2593(%rip), %rdi      # 0x8398
pushq $0x39
popq %rsi
pushq $0x1
popq %rdx
callq 0x23b0
jmp 0x5e5c
movq 0x51df(%rip), %rax      # 0xaff8
movq (%rax), %rcx
leaq 0x25af(%rip), %rdi      # 0x83d2
pushq $0x37
popq %rsi
pushq $0x1
popq %rdx
callq 0x23b0
jmp 0x5e54
movq 0x51c1(%rip), %rax      # 0xaff8
movq (%rax), %rcx
leaq 0x25c9(%rip), %rdi      # 0x840a
pushq $0x35
popq %rsi
pushq $0x1
popq %rdx
callq 0x23b0
movq %r15, %rdi
callq 0x5e60
movq %rbx, %rdi
callq 0x2030
xorl %ebx, %ebx
jmp 0x5de2