// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/deps/jemalloc/src/chunk_dss.c
// Function: chunk_alloc_dss
void *
chunk_alloc_dss(size_t size, size_t alignment, bool *zero)
{
	void *ret;

	cassert(config_dss);
	assert(size > 0 && (size & chunksize_mask) == 0);
	assert(alignment > 0 && (alignment & chunksize_mask) == 0);

	/*
	 * sbrk() uses a signed increment argument, so take care not to
	 * interpret a huge allocation request as a negative increment.
	 */
	if ((intptr_t)size < 0)
		return (NULL);

	malloc_mutex_lock(&dss_mtx);
	if (dss_prev != (void *)-1) {
		size_t gap_size, cpad_size;
		void *cpad, *dss_next;
		intptr_t incr;

		/*
		 * The loop is necessary to recover from races with other
		 * threads that are using the DSS for something other than
		 * malloc.
		 */
		do {
			/* Get the current end of the DSS. */
			dss_max = sbrk(0);
			/*
			 * Calculate how much padding is necessary to
			 * chunk-align the end of the DSS.
			 */
			gap_size = (chunksize - CHUNK_ADDR2OFFSET(dss_max)) &
			    chunksize_mask;
			/*
			 * Compute how much chunk-aligned pad space (if any) is
			 * necessary to satisfy alignment.  This space can be
			 * recycled for later use.
			 */
			cpad = (void *)((uintptr_t)dss_max + gap_size);
			ret = (void *)ALIGNMENT_CEILING((uintptr_t)dss_max,
			    alignment);
			cpad_size = (uintptr_t)ret - (uintptr_t)cpad;
			dss_next = (void *)((uintptr_t)ret + size);
			if ((uintptr_t)ret < (uintptr_t)dss_max ||
			    (uintptr_t)dss_next < (uintptr_t)dss_max) {
				/* Wrap-around. */
				malloc_mutex_unlock(&dss_mtx);
				return (NULL);
			}
			incr = gap_size + cpad_size + size;
			dss_prev = sbrk(incr);
			if (dss_prev == dss_max) {
				/* Success. */
				dss_max = dss_next;
				malloc_mutex_unlock(&dss_mtx);
				if (cpad_size != 0)
					chunk_unmap(cpad, cpad_size);
				if (*zero) {
					VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
					memset(ret, 0, size);
				}
				return (ret);
			}
		} while (dss_prev != (void *)-1);
	}
	malloc_mutex_unlock(&dss_mtx);

	return (NULL);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
testq %rdi, %rdi
js 0x85d38
movq %rsi, %r12
movq %rdi, %rbx
movq %rdx, 0x8(%rsp)
leaq 0x59ca1(%rip), %rdi     # 0xdf938
callq 0x1faa0
cmpq $-0x1, 0x59cbc(%rip)    # 0xdf960
je 0x85d2c
leaq -0x1(%r12), %rax
movq %rax, 0x10(%rsp)
negq %r12
xorl %edi, %edi
callq 0x1f3e0
movq %rax, %r13
movq %rax, 0x59ca0(%rip)     # 0xdf968
movq 0x10(%rsp), %rax
leaq (%rax,%r13), %r14
andq %r12, %r14
cmpq %r13, %r14
jb 0x85d2c
leaq (%r14,%rbx), %r15
cmpq %r13, %r15
jb 0x85d2c
leaq 0x59b77(%rip), %rax     # 0xdf860
movq (%rax), %rdi
leaq 0x59b8d(%rip), %rax     # 0xdf880
movq (%rax), %rax
movq %rax, %rcx
andq %r13, %rcx
subq %rcx, %rdi
andq %rax, %rdi
addq %rdi, %r13
movq %r14, %rbp
subq %r13, %rbp
addq %rbx, %rdi
addq %rbp, %rdi
callq 0x1f3e0
movq %rax, 0x59c43(%rip)     # 0xdf960
cmpq 0x59c44(%rip), %rax     # 0xdf968
je 0x85d4d
cmpq $-0x1, %rax
jne 0x85cb7
leaq 0x59c05(%rip), %rdi     # 0xdf938
callq 0x1fbb0
xorl %r14d, %r14d
movq %r14, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r15, 0x59c14(%rip)     # 0xdf968
leaq 0x59bdd(%rip), %rdi     # 0xdf938
callq 0x1fbb0
cmpq %r13, %r14
je 0x85d70
movq %r13, %rdi
movq %rbp, %rsi
callq 0x859c1
movq 0x8(%rsp), %rax
cmpb $0x1, (%rax)
jne 0x85d3b
leaq 0x20(%rsp), %rax
movq $0x4d430001, (%rax)     # imm = 0x4D430001
movq %r14, 0x8(%rax)
movq %rbx, 0x10(%rax)
xorl %ecx, %ecx
movq %rcx, 0x18(%rax)
movq %rcx, 0x20(%rax)
movq %rcx, 0x28(%rax)
xorl %edx, %edx
rolq $0x3, %rdi
rolq $0xd, %rdi
rolq $0x3d, %rdi
rolq $0x33, %rdi
xchgq %rbx, %rbx
movq %rdx, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq %r14, %rdi
xorl %esi, %esi
movq %rbx, %rdx
callq 0x1f110
jmp 0x85d3b