// File: /workspace/github_c_makefile_star2_O1/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 %rbx
movl %edx, %r8d
movq %rsi, %rcx
testl %edi, %edi
je 0x129e
movl %edi, %edx
cmpb $0x0, 0x2ec8(%rip)      # 0x4040
jne 0x11dc
leaq 0x2ecf(%rip), %rax      # 0x4050
movq %rax, 0x2ec0(%rip)      # 0x4048
xorps %xmm0, %xmm0
movaps %xmm0, 0x2ebe(%rip)     # 0x4050
movabsq $0x619000000001, %rsi   # imm = 0x619000000001
movq %rsi, 0x2ebd(%rip)      # 0x4060
movb $0x1, 0x2e96(%rip)      # 0x4040
leaq 0x904f(%rip), %rdi      # 0xa200
xorl %esi, %esi
cmpq $0x0, (%rdi)
je 0x11ce
incq %rsi
addq $0x8, %rdi
cmpq $0x412, %rsi            # imm = 0x412
jne 0x11b3
movl $0x1, %esi
movslq %esi, %rsi
leaq 0x9028(%rip), %rdi      # 0xa200
movq %rax, (%rdi,%rsi,8)
movq 0x2e65(%rip), %rax      # 0x4048
movslq 0x14(%rax), %rsi
cmpl %edx, %esi
jb 0x11f1
cmpl $0x0, 0x10(%rax)
jne 0x1219
movq 0x8(%rax), %rax
testq %rax, %rax
jne 0x11e3
movq 0x2df7(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xe39(%rip), %rsi       # 0x2044
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x1030
jmp 0x1299
movl %edx, %ecx
leaq 0x18(%rcx), %rdi
cmpq %rsi, %rdi
jbe 0x1234
movl $0x0, 0x10(%rax)
addq $0x18, %rax
movq %rax, %rbx
jmp 0x1299
leaq 0x18(%rax), %rbx
addq %rax, %rcx
addq $0x18, %rcx
movq %rax, (%rcx)
movq 0x8(%rax), %rdi
movq %rdi, 0x8(%rcx)
subl %edx, %esi
addl $-0x18, %esi
movl %esi, 0x14(%rcx)
movl $0x1, 0x10(%rcx)
leaq 0x8fa0(%rip), %rdi      # 0xa200
xorl %esi, %esi
cmpq $0x0, (%rdi)
je 0x127d
incq %rsi
addq $0x8, %rdi
cmpq $0x412, %rsi            # imm = 0x412
jne 0x1262
movl $0x1, %esi
movslq %esi, %rsi
leaq 0x8f79(%rip), %rdi      # 0xa200
movq %rcx, (%rdi,%rsi,8)
movl %edx, 0x14(%rax)
movl $0x0, 0x10(%rax)
movq %rcx, 0x8(%rax)
movq %rbx, %rax
popq %rbx
retq
movq 0x2d53(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xd5d(%rip), %rsi       # 0x200c
xorl %ebx, %ebx
movq %rcx, %rdx
movl %r8d, %ecx
xorl %eax, %eax
callq 0x1030
jmp 0x1299