// File: /workspace/github_c_makefile_star2_O2/codeniko[P]CS214-Malloc-Free/mymalloc.c
// Function: mymalloc
void *mymalloc(unsigned int size, char *file, int line)
{
	static int initialized = 0;
	struct MemEntry *p;
	struct MemEntry *next;
	static struct MemEntry *root;
	
	if (size == 0) {
		fprintf(stderr, "Unable to allocate 0 bytes in FILE: '%s' on LINE: '%d'\n", file, line);
		return 0;
	}

	if(!initialized)	// 1st time called
	{
		// create a root chunk at the beginning of the memory block
		root = (struct MemEntry*) memblock;
		root->prev = root->next = 0;
		root->size = MEMSIZE - sizeof(struct MemEntry);
		root->isfree = 1;
		initialized = 1;
		memEntries[getFreeIndex()] = memblock;
	}

	p = root;
	do
	{
		if(p->size < size || !p->isfree) {
			// the current chunk is smaller, go to the next chunk
			// or this chunk was taken, go to the next
			p = p->next;
		}
		else if(p->size < (size + sizeof(struct MemEntry))) {
			// this chunk is free and large enough to hold data, 
			// but there's not enough memory to hold the HEADER of the next chunk
			// don't create any more chunks after this one
			p->isfree = 0;
			return (char*)p + sizeof(struct MemEntry);
		}
		else {
			// take the needed memory and create the header of the next chunk
			next = (struct MemEntry*)((char*)p + sizeof(struct MemEntry) + size);
			next->prev = p;
			next->next = p->next;
			next->size = p->size - sizeof(struct MemEntry) - size;
			next->isfree = 1;
			memEntries[getFreeIndex()] = next;
			p->size = size;
			p->isfree = 0;
			p->next = next;
			return (char*)p + sizeof(struct MemEntry);
		}
	} while (p != 0);

	fprintf(stderr, "Insufficient memory space requested (%d bytes) in FILE: '%s' on LINE: '%d'\n", size, file, line);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %ebp
movq %rsi, %r14
testl %edi, %edi
je 0x1277
movl %edi, %ebx
cmpb $0x1, 0x2ec2(%rip)      # 0x4040
jne 0x1189
movq 0x2ec1(%rip), %r12      # 0x4048
jmp 0x11cb
leaq 0x2ec0(%rip), %r12      # 0x4050
movq %r12, 0x2eb1(%rip)      # 0x4048
xorps %xmm0, %xmm0
movaps %xmm0, 0x2eaf(%rip)     # 0x4050
movabsq $0x619000000001, %rax   # imm = 0x619000000001
movq %rax, 0x2eae(%rip)      # 0x4060
movb $0x1, 0x2e87(%rip)      # 0x4040
callq 0x1370
cltq
leaq 0x9039(%rip), %rcx      # 0xa200
movq %r12, (%rcx,%rax,8)
movslq 0x14(%r12), %rax
cmpl %ebx, %eax
jb 0x11dc
cmpl $0x0, 0x10(%r12)
jne 0x120b
movq 0x8(%r12), %r12
testq %r12, %r12
jne 0x11cb
movq 0x2e0b(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xe4d(%rip), %rsi       # 0x2044
xorl %r15d, %r15d
movl %ebx, %edx
movq %r14, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x1030
jmp 0x126b
movl %ebx, %ecx
leaq 0x18(%rcx), %rdx
leaq 0x18(%r12), %r15
cmpq %rax, %rdx
jbe 0x1223
andl $0x0, 0x10(%r12)
jmp 0x126b
leaq (%r15,%rcx), %r14
movq %r12, 0x18(%r12,%rcx)
movq 0x8(%r12), %rdx
movq %rdx, 0x20(%r12,%rcx)
subl %ebx, %eax
addl $-0x18, %eax
movl %eax, 0x2c(%r12,%rcx)
movl $0x1, 0x28(%r12,%rcx)
callq 0x1370
cltq
leaq 0x8fa9(%rip), %rcx      # 0xa200
movq %r14, (%rcx,%rax,8)
movl %ebx, 0x14(%r12)
andl $0x0, 0x10(%r12)
movq %r14, 0x8(%r12)
movq %r15, %rax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x2d7a(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xd84(%rip), %rsi       # 0x200c
xorl %r15d, %r15d
movq %r14, %rdx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x1030
jmp 0x126b