// File: /workspace/github_c_makefile_star2_O0/nh13[P]ksw/src/ksw2/kalloc.c
// Function: kmalloc
void *kmalloc(void *_km, size_t n_bytes)
{
	kmem_t *km = (kmem_t*)_km;
	size_t n_units, *p, *q;

	if (n_bytes == 0) return 0;
	if (km == 0) return malloc(n_bytes);
	/* "n_units" means the number of units. The size of one unit equals to sizeof(kheader_t).
	 * "1" is the kheader_t of a block, which is always required. */
	n_units = 1 + (n_bytes + sizeof(size_t) - 1) / sizeof(size_t);
	if (n_units&1) ++n_units; /* make n_units an even number, or it will segfault if only one unit remains */

	if (!(q = km->loop_head)) { /* the first time when kmalloc() is called, intialization */
		km->base[1] = (size_t)(km->loop_head = q = km->base); *q = 0;
	}
	for (p = PTR(q);; q = p, p = PTR(p)) { /* search for a suitable block */
		if (*p >= n_units) { /* p->size if the size of current block. This line means the current block is large enough. */
			if (*p == n_units) q[1] = (size_t)PTR(p); /* no need to split the block */
			else { /* split the block */
				/* memory is allocated at the end of the block */
				*p -= n_units; /* reduce the size of the free block */
				p += *p; /* skip to the kheader_t of the allocated block */
				*p = n_units; /* set the size */
			}
			km->loop_head = q; /* set the end of chain */
			return p + 1; /* skip the kheader_t */
		}
		if (p == km->loop_head) { /* then ask for more "cores" */
			if ((p = morecore(km, n_units)) == 0) return 0;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x19e74c
movq $0x0, -0x8(%rbp)
jmp 0x19e899
cmpq $0x0, -0x20(%rbp)
jne 0x19e765
movq -0x18(%rbp), %rdi
callq 0x19e150
movq %rax, -0x8(%rbp)
jmp 0x19e899
movq -0x18(%rbp), %rax
addq $0x8, %rax
subq $0x1, %rax
shrq $0x3, %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x19e797
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, %rax
jne 0x19e7cc
movq -0x20(%rbp), %rcx
movq %rcx, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq $0x0, (%rax)
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
cmpq -0x28(%rbp), %rax
jb 0x19e84d
movq -0x30(%rbp), %rax
movq (%rax), %rax
cmpq -0x28(%rbp), %rax
jne 0x19e804
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x19e833
movq -0x28(%rbp), %rdx
movq -0x30(%rbp), %rax
movq (%rax), %rcx
subq %rdx, %rcx
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rax
shlq $0x3, %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x8(%rbp)
jmp 0x19e899
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x19e87e
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x19e8b0
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jne 0x19e87c
movq $0x0, -0x8(%rbp)
jmp 0x19e899
jmp 0x19e87e
jmp 0x19e880
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x19e7d8
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)