// File: tewalds[P]morat/hex/../lib/compacttree.h
// Function: Morat::CompactTree<Morat::Hex::AgentMCTS::Node>::alloc(unsigned int, Morat::CompactTree<Morat::Hex::AgentMCTS::Node>::Data**)
Data * alloc(unsigned int num, Data ** parent){
		assert(num > 0 && num < MAX_NUM);

		unsigned int size = sizeof(Data) + sizeof(Node)*num;
		PLUS(memused, size);

	//check freelist
		if(Data * t = freelist.pop(num)){
			assert(t->empty() && t->capacity == num);
			return new(t) Data(num, parent);
		}

	//allocate new memory
		while(1){
			Chunk * c = current;
			uint32_t used = c->used;
			if(used + size <= c->capacity){ //if there is room, try to use it
				if(CAS(c->used, used, used+size))
					return new((Data *)(c->mem + used)) Data(num, parent);
				else
					continue;
			}else if(c->next != NULL){ //if there is a next chunk, advance to it and try again
				CAS(current, c, c->next); //CAS to avoid skipping a chunk
				CAS(last, c, c->next); //most last forward too
				continue;
			}else{ //need to allocate a new chunk
				Chunk * next = new Chunk(CHUNK_SIZE);

				while(1){
					while(c->next != NULL) //advance to the end
						c = c->next;

					next->id = c->id+1;
					if(CAS(c->next, (Chunk *)NULL, next)){ //put it in place
						INCR(numchunks);
						//note that this doesn't move current forward since this may not be the next chunk
						// if there is a race condition where two threads allocate chunks at the same time
						break;
					}
				}
				continue;
			}
		}
		assert(false && "How'd CompactTree::alloc get here?");
		return NULL;
	}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movl %esi, 0x84(%rsp)
movq %rdx, 0x78(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x28(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x84(%rsp)
movb %al, 0x37(%rsp)
jbe 0x1ff1a
cmpl $0x272, 0x84(%rsp) # imm = 0x272
setb %al
movb %al, 0x37(%rsp)
movb 0x37(%rsp), %al
testb $0x1, %al
jne 0x1ff24
jmp 0x1ff26
jmp 0x1ff45
leaq 0x2da00(%rip), %rdi     # 0x4d92d
leaq 0x2d734(%rip), %rsi     # 0x4d668
movl $0x139, %edx            # imm = 0x139
leaq 0x2da06(%rip), %rcx     # 0x4d946
callq 0x52a0
movq 0x28(%rsp), %rdi
movl 0x84(%rsp), %eax
imulq $0x30, %rax, %rax
addq $0x40, %rax
movl %eax, 0x74(%rsp)
addq $0x13b8, %rdi           # imm = 0x13B8
leaq 0x74(%rsp), %rsi
callq 0x1d5c0
movq 0x28(%rsp), %rdi
addq $0x20, %rdi
movl 0x84(%rsp), %esi
callq 0x201c0
movq %rax, 0x68(%rsp)
cmpq $0x0, 0x68(%rsp)
je 0x2001c
movq 0x68(%rsp), %rdi
callq 0x1e600
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x27(%rsp)
jne 0x1ffad
jmp 0x1ffc4
movq 0x68(%rsp), %rax
movzwl 0x4(%rax), %eax
cmpl 0x84(%rsp), %eax
sete %al
movb %al, 0x27(%rsp)
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x1ffce
jmp 0x1ffd0
jmp 0x1ffef
leaq 0x2d9e8(%rip), %rdi     # 0x4d9bf
leaq 0x2d68a(%rip), %rsi     # 0x4d668
movl $0x140, %edx            # imm = 0x140
leaq 0x2d95c(%rip), %rcx     # 0x4d946
callq 0x52a0
movq 0x68(%rsp), %rdi
movq %rdi, 0x18(%rsp)
movl 0x84(%rsp), %esi
movq 0x78(%rsp), %rdx
callq 0x20220
movq 0x18(%rsp), %rax
movq %rax, 0x90(%rsp)
jmp 0x2019f
jmp 0x2001e
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movl 0x10(%rax), %eax
movl %eax, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
addl 0x74(%rsp), %eax
movq 0x60(%rsp), %rcx
cmpl 0xc(%rcx), %eax
ja 0x200b1
movq 0x60(%rsp), %rdi
addq $0x10, %rdi
movl 0x5c(%rsp), %eax
addl 0x74(%rsp), %eax
movl %eax, 0x58(%rsp)
leaq 0x5c(%rsp), %rsi
leaq 0x58(%rsp), %rdx
callq 0x203d0
testb $0x1, %al
jne 0x20074
jmp 0x200ac
movq 0x60(%rsp), %rax
movq 0x18(%rax), %rdi
movl 0x5c(%rsp), %eax
addq %rax, %rdi
movq %rdi, 0x10(%rsp)
movl 0x84(%rsp), %esi
movq 0x78(%rsp), %rdx
callq 0x20220
movq 0x10(%rsp), %rax
movq %rax, 0x90(%rsp)
jmp 0x2019f
jmp 0x2001e
movq 0x60(%rsp), %rax
cmpq $0x0, (%rax)
je 0x200f1
movq 0x28(%rsp), %rdi
addq $0x8, %rdi
movq 0x60(%rsp), %rdx
leaq 0x60(%rsp), %rsi
callq 0x20400
movq 0x28(%rsp), %rdi
addq $0x10, %rdi
movq 0x60(%rsp), %rdx
leaq 0x60(%rsp), %rsi
callq 0x20400
jmp 0x2001e
movl $0x20, %edi
callq 0x5400
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x8(%rsp)
movl $0x1000000, %esi        # imm = 0x1000000
callq 0x20440
jmp 0x20112
movq 0x8(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0x2011e
movq 0x60(%rsp), %rax
cmpq $0x0, (%rax)
je 0x20152
movq 0x60(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x60(%rsp)
jmp 0x2011e
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
callq 0x53a0
jmp 0x201af
movq 0x60(%rsp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movq 0x50(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x60(%rsp), %rdi
movq $0x0, 0x38(%rsp)
leaq 0x38(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0x20400
testb $0x1, %al
jne 0x20188
jmp 0x20198
movq 0x28(%rsp), %rdi
addq $0x18, %rdi
callq 0x20490
jmp 0x2019a
jmp 0x2011c
jmp 0x2001e
movq 0x90(%rsp), %rax
addq $0x98, %rsp
retq
movq 0x48(%rsp), %rdi
callq 0x5760
nopl (%rax)