// File: tewalds[P]morat/hex/../lib/agentpool.h
// Function: Morat::AgentThreadBase<Morat::Hex::AgentMCTS>::run()
void run(){
		while(true){
			switch(pool->thread_state){
			case Thread_Cancelled:  //threads should exit
				return;

			case Thread_Wait_Start: //threads are waiting to start
			case Thread_Wait_Start_Cancelled:
				pool->run_barrier.wait();
				CAS(pool->thread_state, Thread_Wait_Start, Thread_Running);
				CAS(pool->thread_state, Thread_Wait_Start_Cancelled, Thread_Cancelled);
				break;

			case Thread_Wait_End:   //threads are waiting to end
				pool->run_barrier.wait();
				CAS(pool->thread_state, Thread_Wait_End, Thread_Wait_Start);
				break;

			case Thread_Running:    //threads are running
				if(agent->done()){ //solved or finished runs
					CAS(pool->thread_state, Thread_Running, Thread_Wait_End);
					break;
				}
				if(agent->need_gc()){ //out of memory, start garbage collection
					CAS(pool->thread_state, Thread_Running, Thread_GC);
					break;
				}
				iterate();
				break;

			case Thread_GC:         //one thread is running garbage collection, the rest are waiting
			case Thread_GC_End:     //once done garbage collecting, go to wait_end instead of back to running
				if(pool->gc_barrier.wait()){
					agent->start_gc();
					CAS(pool->thread_state, Thread_GC,     Thread_Running);
					CAS(pool->thread_state, Thread_GC_End, Thread_Wait_End);
				}
				pool->gc_barrier.wait();
				break;
			}
		}
	}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rax
movl (%rax), %eax
movq %rax, 0x8(%rsp)
subq $0x6, %rax
ja 0x23f6d
movq 0x8(%rsp), %rax
leaq 0x294ab(%rip), %rcx     # 0x4d244
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
addq $0x58, %rsp
retq
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
addq $0x20, %rdi
callq 0x21b40
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
movl $0x1, 0x4c(%rsp)
movl $0x3, 0x48(%rsp)
leaq 0x4c(%rsp), %rsi
leaq 0x48(%rsp), %rdx
callq 0x21c20
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
movl $0x2, 0x44(%rsp)
movl $0x0, 0x40(%rsp)
leaq 0x44(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x21c20
jmp 0x23f6d
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
addq $0x20, %rdi
callq 0x21b40
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
movl $0x6, 0x3c(%rsp)
movl $0x1, 0x38(%rsp)
leaq 0x3c(%rsp), %rsi
leaq 0x38(%rsp), %rdx
callq 0x21c20
jmp 0x23f6d
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x24730
testb $0x1, %al
jne 0x23e61
jmp 0x23e8e
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
movl $0x3, 0x34(%rsp)
movl $0x6, 0x30(%rsp)
leaq 0x34(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x21c20
jmp 0x23f6d
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x247e0
testb $0x1, %al
jne 0x23ea2
jmp 0x23ecf
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
movl $0x3, 0x2c(%rsp)
movl $0x4, 0x28(%rsp)
leaq 0x2c(%rsp), %rsi
leaq 0x28(%rsp), %rdx
callq 0x21c20
jmp 0x23f6d
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
callq *0x20(%rax)
jmp 0x23f6d
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
addq $0x80, %rdi
callq 0x21b40
testb $0x1, %al
jne 0x23efa
jmp 0x23f58
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x24820
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
movl $0x4, 0x24(%rsp)
movl $0x3, 0x20(%rsp)
leaq 0x24(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x21c20
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
movl $0x5, 0x1c(%rsp)
movl $0x6, 0x18(%rsp)
leaq 0x1c(%rsp), %rsi
leaq 0x18(%rsp), %rdx
callq 0x21c20
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rdi
addq $0x80, %rdi
callq 0x21b40
jmp 0x23d73
nopw %cs:(%rax,%rax)
nopl (%rax)