// File: /workspace/github_c_makefile_star2_O3/albertito[P]libfiu/libfiu/fiu.c
// Function: fiu_fail
int fiu_fail(const char *name)
{
	struct pf_info *pf;
	int failnum;

	rec_count++;

	/* We must do this before acquiring the lock and calling any
	 * (potentially wrapped) functions. */
	if (rec_count > 1) {
		rec_count--;
		return 0;
	}

	ef_rlock();

	/* It can happen that someone calls fiu_fail() before fiu_init(); we
	 * don't want to crash so we just exit. */
	if (enabled_fails == NULL) {
		goto exit;
	}

	pf = wtable_get(enabled_fails, name);

	/* None found. */
	if (pf == NULL) {
		goto exit;
	}

	if (pf->flags & FIU_ONETIME) {
		pthread_mutex_lock(&pf->lock);
		if (pf->failed_once) {
			pthread_mutex_unlock(&pf->lock);
			goto exit;
		}
		/* We leave it locked so we don't accidentally fail this
		 * point twice. */
	}

	switch (pf->method) {
	case PF_ALWAYS:
		goto exit_fail;
		break;
	case PF_PROB:
		if (pf->minfo.probability > randd())
			goto exit_fail;
		break;
	case PF_EXTERNAL:
		if (pf->minfo.external_cb(pf->name, &(pf->failnum),
		                          &(pf->failinfo), &(pf->flags)))
			goto exit_fail;
		break;
	case PF_STACK:
		if (should_stack_fail(pf))
			goto exit_fail;
		break;
	default:
		break;
	}

	if (pf->flags & FIU_ONETIME) {
		pthread_mutex_unlock(&pf->lock);
	}

exit:
	trace("FIU  Not failing %s\n", name);

	ef_runlock();
	rec_count--;
	return 0;

exit_fail:
	trace("FIU  Failing %s on %s\n", name, pf->name);

	pthread_setspecific(last_failinfo_key, pf->failinfo);
	failnum = pf->failnum;

	if (pf->flags & FIU_ONETIME) {
		pf->failed_once = true;
		pthread_mutex_unlock(&pf->lock);
	}

	ef_runlock();
	rec_count--;
	return failnum;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x338, %rsp            # imm = 0x338
movq %rdi, %r14
leaq 0x5a0b(%rip), %rdi      # 0x7fd8
callq 0x21e0
movq %rax, %rbx
movl (%rax), %eax
leal 0x1(%rax), %ecx
movl %ecx, (%rbx)
xorl %ebp, %ebp
testl %eax, %eax
jg 0x276c
leaq 0x5be8(%rip), %rdi      # 0x81d8
callq 0x21a0
leaq 0x5bcc(%rip), %rax      # 0x81c8
movq (%rax), %rdi
xorl %ebp, %ebp
testq %rdi, %rdi
je 0x275c
movq %r14, %rsi
callq 0x33c0
testq %rax, %rax
je 0x275c
movq %rax, %r14
testb $0x1, 0x18(%rax)
je 0x263f
leaq 0x20(%r14), %r15
movq %r15, %rdi
callq 0x2340
cmpb $0x1, 0x48(%r14)
jne 0x263f
movq %r15, %rdi
jmp 0x2757
leaq 0x18(%r14), %r15
movl 0x4c(%r14), %eax
decl %eax
cmpl $0x3, %eax
ja 0x274a
leaq 0x29af(%rip), %rcx      # 0x5008
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorps %xmm0, %xmm0
cvtss2sd 0x50(%r14), %xmm0
imull $0x41c64e6d, 0x5b43(%rip), %eax # imm = 0x41C64E6D
addl $0x3039, %eax           # imm = 0x3039
movl %eax, 0x5b38(%rip)      # 0x81b8
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
divsd 0x2970(%rip), %xmm1     # 0x5000
ucomisd %xmm1, %xmm0
ja 0x26b5
jmp 0x274a
movq (%r14), %rdi
leaq 0xc(%r14), %rsi
leaq 0x10(%r14), %rdx
movq %r15, %rcx
callq *0x50(%r14)
testl %eax, %eax
je 0x274a
movl 0x5b55(%rip), %edi      # 0x8210
movq 0x10(%r14), %rsi
callq 0x2350
movl 0xc(%r14), %ebp
testb $0x1, 0x18(%r14)
je 0x275c
movb $0x1, 0x48(%r14)
jmp 0x2750
movq %r15, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
movl $0x64, %esi
callq 0x3158
testl %eax, %eax
jle 0x2745
movl %eax, %r12d
xorl %r13d, %r13d
movq 0x10(%rsp,%r13,8), %rdi
movq 0x50(%r14), %r15
movq 0x58(%r14), %rax
testq %rax, %rax
je 0x271c
cmpq %rdi, %r15
setbe %cl
cmpq %rdi, %rax
setae %al
testb %cl, %al
jne 0x2726
jmp 0x273d
callq 0x315d
cmpq %rax, %r15
jne 0x273d
movl 0x60(%r14), %eax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %rax
je 0x26b5
cmpq %rax, %r13
je 0x26b5
incq %r13
cmpq %r13, %r12
jne 0x26f8
movq 0x8(%rsp), %r15
testb $0x1, (%r15)
je 0x275c
addq $0x20, %r14
movq %r14, %rdi
callq 0x2230
leaq 0x5a75(%rip), %rdi      # 0x81d8
callq 0x2260
movl (%rbx), %eax
decl %eax
movl %eax, (%rbx)
movl %ebp, %eax
addq $0x338, %rsp            # imm = 0x338
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq